diff --git a/Mage.Sets/src/mage/cards/a/Aetherling.java b/Mage.Sets/src/mage/cards/a/Aetherling.java
index 6e7020a9580..ff6d6b5f8a0 100644
--- a/Mage.Sets/src/mage/cards/a/Aetherling.java
+++ b/Mage.Sets/src/mage/cards/a/Aetherling.java
@@ -29,7 +29,7 @@ public final class Aetherling extends CardImpl {
this.toughness = new MageInt(5);
// {U}: Exile Aetherling. Return it to the battlefield under its owner's control at the beginning of the next end step.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true), new ManaCostsImpl("{U}")));
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(), new ManaCostsImpl("{U}")));
// {U}: Aetherling can't be blocked this turn
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{U}")));
// {1}: Aetherling gets +1/-1 until end of turn.
diff --git a/Mage.Sets/src/mage/cards/a/Alms.java b/Mage.Sets/src/mage/cards/a/Alms.java
index db16df42257..bf6b4c84e4e 100644
--- a/Mage.Sets/src/mage/cards/a/Alms.java
+++ b/Mage.Sets/src/mage/cards/a/Alms.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileTopCardOfGraveyardCost;
@@ -11,21 +9,23 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class Alms extends CardImpl {
public Alms(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
// {1}, Exile the top card of your graveyard: Prevent the next 1 damage that would be dealt to target creature this turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1));
- ability.addCost(new ExileTopCardOfGraveyardCost(1));
+ Ability ability = new SimpleActivatedAbility(
+ new PreventDamageToTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1)
+ );
+ ability.addCost(new ExileTopCardOfGraveyardCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java b/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
index 1668edee293..c509e050fa2 100644
--- a/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
+++ b/Mage.Sets/src/mage/cards/a/AnuridBrushhopper.java
@@ -29,7 +29,7 @@ public final class AnuridBrushhopper extends CardImpl {
// Discard two cards: Exile Anurid Brushhopper. Return it to the battlefield under its owner's control at the beginning of the next end step.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true),
+ new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(),
new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards")))));
}
diff --git a/Mage.Sets/src/mage/cards/f/FreneticSliver.java b/Mage.Sets/src/mage/cards/f/FreneticSliver.java
index 49275b38b04..8c33b99f5f8 100644
--- a/Mage.Sets/src/mage/cards/f/FreneticSliver.java
+++ b/Mage.Sets/src/mage/cards/f/FreneticSliver.java
@@ -77,7 +77,7 @@ class FreneticSliverEffect extends OneShotEffect {
return false;
}
if (player.flipCoin(source, game, true)) {
- return new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true).apply(game, source);
+ return new ExileReturnBattlefieldOwnerNextEndStepSourceEffect().apply(game, source);
} else {
return perm.sacrifice(source, game);
}
diff --git a/Mage.Sets/src/mage/cards/g/GhostCouncilOfOrzhova.java b/Mage.Sets/src/mage/cards/g/GhostCouncilOfOrzhova.java
index 51099f92ec8..08c01994e6e 100644
--- a/Mage.Sets/src/mage/cards/g/GhostCouncilOfOrzhova.java
+++ b/Mage.Sets/src/mage/cards/g/GhostCouncilOfOrzhova.java
@@ -44,7 +44,7 @@ public final class GhostCouncilOfOrzhova extends CardImpl {
// {1}, Sacrifice a creature: Exile Ghost Council of Orzhova. Return it to the battlefield under its owner's control at the beginning of the next end step.
ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
- new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true),
+ new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(),
new GenericManaCost(1));
ability.addCost(new SacrificeTargetCost(
new TargetControlledCreaturePermanent(
diff --git a/Mage.Sets/src/mage/cards/h/HikariTwilightGuardian.java b/Mage.Sets/src/mage/cards/h/HikariTwilightGuardian.java
index 116f61bd0c9..ac55282303b 100644
--- a/Mage.Sets/src/mage/cards/h/HikariTwilightGuardian.java
+++ b/Mage.Sets/src/mage/cards/h/HikariTwilightGuardian.java
@@ -31,7 +31,7 @@ public final class HikariTwilightGuardian extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a Spirit or Arcane spell, you may exile Hikari, Twilight Guardian. If you do, return it to the battlefield under its owner's control at the beginning of the next end step.
- Effect effect = new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true);
+ Effect effect = new ExileReturnBattlefieldOwnerNextEndStepSourceEffect();
effect.setText("you may exile {this}. If you do, return it to the battlefield under its owner's control at the beginning of the next end step");
this.addAbility(new SpellCastControllerTriggeredAbility(effect, StaticFilters.FILTER_SPIRIT_OR_ARCANE_CARD, true));
}
diff --git a/Mage.Sets/src/mage/cards/n/NaturesKiss.java b/Mage.Sets/src/mage/cards/n/NaturesKiss.java
index 4ba50dcd6e5..7c235419058 100644
--- a/Mage.Sets/src/mage/cards/n/NaturesKiss.java
+++ b/Mage.Sets/src/mage/cards/n/NaturesKiss.java
@@ -1,32 +1,30 @@
-
package mage.cards.n;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileTopCardOfGraveyardCost;
-import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.SubType;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class NaturesKiss extends CardImpl {
public NaturesKiss(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.subtype.add(SubType.AURA);
// Enchant creature
@@ -34,10 +32,12 @@ public final class NaturesKiss extends CardImpl {
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
-
+
// {1}, Exile the top card of your graveyard: Enchanted creature gets +1/+1 until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{1}"));
- ability.addCost(new ExileTopCardOfGraveyardCost(1));
+ Ability ability = new SimpleActivatedAbility(new BoostEnchantedEffect(
+ 1, 1, Duration.EndOfTurn
+ ), new GenericManaCost(1));
+ ability.addCost(new ExileTopCardOfGraveyardCost());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/n/NezahalPrimalTide.java b/Mage.Sets/src/mage/cards/n/NezahalPrimalTide.java
index 9ad28f9576d..d1eae780649 100644
--- a/Mage.Sets/src/mage/cards/n/NezahalPrimalTide.java
+++ b/Mage.Sets/src/mage/cards/n/NezahalPrimalTide.java
@@ -58,7 +58,7 @@ public final class NezahalPrimalTide extends CardImpl {
new DrawCardSourceControllerEffect(1), filter, false, SetTargetPointer.NONE));
// Discard three cards: Exile Nezahal. Return it to the battlefield tapped under its owner's control at the beginning of the next end step.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true, true),
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true),
new DiscardTargetCost(new TargetCardInHand(3, new FilterCard("three cards")))));
}
diff --git a/Mage.Sets/src/mage/cards/n/NorinTheWary.java b/Mage.Sets/src/mage/cards/n/NorinTheWary.java
index dd19ec242e5..6778ecf1a86 100644
--- a/Mage.Sets/src/mage/cards/n/NorinTheWary.java
+++ b/Mage.Sets/src/mage/cards/n/NorinTheWary.java
@@ -13,7 +13,6 @@ import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
/**
*
@@ -48,7 +47,7 @@ public final class NorinTheWary extends CardImpl {
class NorinTheWaryTriggeredAbility extends TriggeredAbilityImpl {
public NorinTheWaryTriggeredAbility() {
- super(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true), false);
+ super(Zone.BATTLEFIELD, new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(), false);
}
public NorinTheWaryTriggeredAbility(final NorinTheWaryTriggeredAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/s/Saltskitter.java b/Mage.Sets/src/mage/cards/s/Saltskitter.java
index 673cf8c5c84..eca33af6caa 100644
--- a/Mage.Sets/src/mage/cards/s/Saltskitter.java
+++ b/Mage.Sets/src/mage/cards/s/Saltskitter.java
@@ -32,7 +32,7 @@ public final class Saltskitter extends CardImpl {
this.toughness = new MageInt(4);
// Whenever another creature enters the battlefield, exile Saltskitter. Return Saltskitter to the battlefield under its owner's control at the beginning of the next end step.
- this.addAbility(new EntersBattlefieldAllTriggeredAbility(new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true), filter));
+ this.addAbility(new EntersBattlefieldAllTriggeredAbility(new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(), filter));
}
private Saltskitter(final Saltskitter card) {
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ReboundTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ReboundTest.java
index 889788ec3d2..60e56bdcf2f 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ReboundTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ReboundTest.java
@@ -64,7 +64,7 @@ public class ReboundTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Distortion Strike", "Memnite");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
- execute();
+ execute();assertAllCommandsUsed();
//check exile and graveyard
assertPowerToughness(playerA, "Memnite", 2, 1);
diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java
index e6dcf15e195..51fad57ba09 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java
@@ -1,7 +1,5 @@
-
package mage.abilities.costs.common;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
@@ -10,8 +8,9 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author magenoxx_at_gmail.com
*/
public class ExileSourceFromGraveCost extends CostImpl {
@@ -20,36 +19,36 @@ public class ExileSourceFromGraveCost extends CostImpl {
this.text = "exile {this} from your graveyard";
}
- public ExileSourceFromGraveCost(ExileSourceFromGraveCost cost) {
+ private ExileSourceFromGraveCost(final ExileSourceFromGraveCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
- if (controller != null) {
- Card card = game.getCard(source.getSourceId());
- if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
- controller.moveCardToExileWithInfo(card, null, "", source, game, Zone.GRAVEYARD, true);
- // 117.11. The actions performed when paying a cost may be modified by effects.
- // Even if they are, meaning the actions that are performed don't match the actions
- // that are called for, the cost has still been paid.
- // so return state here is not important because the user indended to exile the target anyway
- paid = true;
- }
+ if (controller == null) {
+ return paid;
+ }
+ Card card = game.getCard(source.getSourceId());
+ if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
+ controller.moveCards(card, Zone.EXILED, source, game);
+ // 117.11. The actions performed when paying a cost may be modified by effects.
+ // Even if they are, meaning the actions that are performed don't match the actions
+ // that are called for, the cost has still been paid.
+ // so return state here is not important because the user indended to exile the target anyway
+ paid = true;
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- Card card = game.getCard(source.getSourceId());
- return card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD;
+ return game.getCard(source.getSourceId()) != null
+ && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD;
}
@Override
public ExileSourceFromGraveCost copy() {
return new ExileSourceFromGraveCost(this);
}
-
}
diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileTopCardOfGraveyardCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileTopCardOfGraveyardCost.java
index 9784495831c..417910fd555 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/ExileTopCardOfGraveyardCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/ExileTopCardOfGraveyardCost.java
@@ -1,6 +1,5 @@
package mage.abilities.costs.common;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
@@ -9,45 +8,40 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public class ExileTopCardOfGraveyardCost extends CostImpl {
- private final int amount;
-
- public ExileTopCardOfGraveyardCost(int amount) {
- this.amount = amount;
+ public ExileTopCardOfGraveyardCost() {
this.text = "Exile the top card of your graveyard";
}
- public ExileTopCardOfGraveyardCost(ExileTopCardOfGraveyardCost cost) {
+ private ExileTopCardOfGraveyardCost(final ExileTopCardOfGraveyardCost cost) {
super(cost);
- this.amount = cost.amount;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
- if(controller == null) {
+ if (controller == null) {
return false;
}
- return controller.getGraveyard().size() >= amount;
+ return !controller.getGraveyard().isEmpty();
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
- if(controller != null) {
- Card topCard = null;
- for (Card card :controller.getGraveyard().getCards(game)) {
- topCard = card;
- }
- if (topCard != null) {
- controller.moveCardToExileWithInfo(topCard, null, "", source, game, Zone.GRAVEYARD, true);
- paid = true;
- }
+ if (controller == null) {
+ return paid;
+ }
+ Card topCard = controller.getGraveyard().getTopCard(game);
+ if (topCard != null) {
+ controller.moveCards(topCard, Zone.EXILED, source, game);
+ paid = true;
}
return paid;
}
@@ -56,4 +50,4 @@ public class ExileTopCardOfGraveyardCost extends CostImpl {
public ExileTopCardOfGraveyardCost copy() {
return new ExileTopCardOfGraveyardCost(this);
}
-}
\ No newline at end of file
+}
diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileTopCreatureCardOfGraveyardCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileTopCreatureCardOfGraveyardCost.java
index 94e1e91fd00..acaac231f6a 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/ExileTopCreatureCardOfGraveyardCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/ExileTopCreatureCardOfGraveyardCost.java
@@ -1,6 +1,5 @@
package mage.abilities.costs.common;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
@@ -9,8 +8,9 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public class ExileTopCreatureCardOfGraveyardCost extends CostImpl {
@@ -30,7 +30,7 @@ public class ExileTopCreatureCardOfGraveyardCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
- if(controller == null) {
+ if (controller == null) {
return false;
}
return controller.getGraveyard().size() >= amount;
@@ -39,17 +39,19 @@ public class ExileTopCreatureCardOfGraveyardCost extends CostImpl {
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
- if(controller != null) {
- Card topCard = null;
- for (Card card :controller.getGraveyard().getCards(game)) {
- if (card.isCreature(game)) {
- topCard = card;
- }
- }
- if (topCard != null) {
- controller.moveCardToExileWithInfo(topCard, null, "", source, game, Zone.GRAVEYARD, true);
- paid = true;
- }
+ if (controller == null) {
+ return paid;
+ }
+ Card topCard = controller
+ .getGraveyard()
+ .getCards(game)
+ .stream()
+ .filter(card -> card.isCreature(game))
+ .findFirst()
+ .orElse(null);
+ if (topCard != null) {
+ controller.moveCards(topCard, Zone.EXILED, source, game);
+ paid = true;
}
return paid;
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java
index 656a8d387d5..6e9aee91faf 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java
@@ -1,4 +1,3 @@
-
package mage.abilities.effects.common;
import mage.abilities.Ability;
@@ -12,25 +11,20 @@ import mage.players.Player;
import mage.target.TargetCard;
/**
- *
* @author LevelX2
*/
public class ExileCardYouChooseTargetOpponentEffect extends OneShotEffect {
- private FilterCard filter;
-
- public ExileCardYouChooseTargetOpponentEffect() {
- this(new FilterCard("a card"));
- }
+ private final FilterCard filter;
public ExileCardYouChooseTargetOpponentEffect(FilterCard filter) {
super(Outcome.Discard);
- staticText = new StringBuilder("Target opponent reveals their hand. You choose ")
- .append(filter.getMessage()).append(" from it and exile that card").toString();
+ this.staticText = "Target opponent reveals their hand. You choose "
+ + filter.getMessage() + " from it and exile that card";
this.filter = filter;
}
- public ExileCardYouChooseTargetOpponentEffect(final ExileCardYouChooseTargetOpponentEffect effect) {
+ private ExileCardYouChooseTargetOpponentEffect(final ExileCardYouChooseTargetOpponentEffect effect) {
super(effect);
this.filter = effect.filter;
}
@@ -39,26 +33,22 @@ public class ExileCardYouChooseTargetOpponentEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
- Card sourceCard = game.getCard(source.getSourceId());
- if (controller != null && opponent != null) {
- if (!opponent.getHand().isEmpty()) {
- opponent.revealCards(sourceCard != null ? sourceCard.getIdName() + " (" + sourceCard.getZoneChangeCounter(game) + ')' : "Exile", opponent.getHand(), game);
- TargetCard target = new TargetCard(Zone.HAND, filter);
- if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
- Card card = opponent.getHand().get(target.getFirstTarget(), game);
- if (card != null) {
- controller.moveCardToExileWithInfo(card, null, "", source, game, Zone.HAND, true);
- }
- }
- }
- return true;
+ if (controller == null || opponent == null
+ || opponent.getHand().count(filter, game) < 1) {
+ return false;
}
- return false;
+ opponent.revealCards(source, opponent.getHand(), game);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
+ controller.choose(Outcome.Exile, opponent.getHand(), target, game);
+ Card card = opponent.getHand().get(target.getFirstTarget(), game);
+ if (card != null) {
+ controller.moveCards(card, Zone.EXILED, source, game);
+ }
+ return true;
}
@Override
public ExileCardYouChooseTargetOpponentEffect copy() {
return new ExileCardYouChooseTargetOpponentEffect(this);
}
-
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldOwnerNextEndStepSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldOwnerNextEndStepSourceEffect.java
index 3c12c7fc737..405223fe11d 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldOwnerNextEndStepSourceEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldOwnerNextEndStepSourceEffect.java
@@ -1,4 +1,3 @@
-
package mage.abilities.effects.common;
import mage.abilities.Ability;
@@ -9,69 +8,55 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
/**
- *
* @author LevelX2
*/
public class ExileReturnBattlefieldOwnerNextEndStepSourceEffect extends OneShotEffect {
- private boolean returnAlways;
- private boolean returnTapped;
+ private final boolean returnTapped;
public ExileReturnBattlefieldOwnerNextEndStepSourceEffect() {
this(false);
}
- public ExileReturnBattlefieldOwnerNextEndStepSourceEffect(boolean returnAlways) {
- this(returnAlways, false);
- }
-
/**
- *
- * @param returnAlways Return the permanent also if it does not go to exile
- * but is moved to another zone (e.g. command zone by commander replacement
- * effect)
* @param returnTapped Does the source return tapped to the battlefield
*/
- public ExileReturnBattlefieldOwnerNextEndStepSourceEffect(boolean returnAlways, boolean returnTapped) {
+ public ExileReturnBattlefieldOwnerNextEndStepSourceEffect(boolean returnTapped) {
super(Outcome.Benefit);
this.returnTapped = returnTapped;
- this.returnAlways = returnAlways;
- staticText = "exile {this}. Return it to the battlefield "
- + (returnTapped ? "tapped " : "")
- + "under its owner's control at the beginning of the next end step";
+ staticText = "exile {this}. Return it to the battlefield " + (returnTapped ? "tapped " : "") +
+ "under its owner's control at the beginning of the next end step";
}
public ExileReturnBattlefieldOwnerNextEndStepSourceEffect(ExileReturnBattlefieldOwnerNextEndStepSourceEffect effect) {
super(effect);
- this.returnAlways = effect.returnAlways;
this.returnTapped = effect.returnTapped;
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent != null) {
- int zcc = game.getState().getZoneChangeCounter(permanent.getId());
- boolean exiled = controller.moveCardToExileWithInfo(permanent, source.getSourceId(), permanent.getIdName(), source, game, Zone.BATTLEFIELD, true);
- if (exiled || (returnAlways && (zcc == game.getState().getZoneChangeCounter(permanent.getId()) - 1))) {
- //create delayed triggered ability and return it from every public zone it was next moved to
- AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
- new ReturnToBattlefieldUnderOwnerControlSourceEffect(returnTapped, zcc + 1));
- game.addDelayedTriggeredAbility(delayedAbility, source);
- }
- }
+ if (controller == null) {
+ return false;
+ }
+ Permanent permanent = source.getSourcePermanentIfItStillExists(game);
+ if (permanent == null) {
return true;
}
- return false;
+ controller.moveCards(permanent, Zone.EXILED, source, game);
+ //create delayed triggered ability and return it from every public zone it was next moved to
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new ReturnToBattlefieldUnderOwnerControlTargetEffect(returnTapped, true)
+ .setTargetPointer(new FixedTarget(permanent.getId(), game))
+ ), source);
+ return true;
}
@Override
public ExileReturnBattlefieldOwnerNextEndStepSourceEffect copy() {
return new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(this);
}
-
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java
index 366da4513b0..da2b84a2eae 100644
--- a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java
@@ -1,7 +1,11 @@
package mage.abilities.keyword;
+import mage.ApprovingObject;
import mage.MageObject;
-import mage.abilities.*;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.StaticAbility;
+import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCost;
@@ -18,7 +22,6 @@ import mage.game.stack.Spell;
import mage.players.Player;
import java.util.UUID;
-import mage.ApprovingObject;
/**
* 702.33. Madness
@@ -124,13 +127,17 @@ class MadnessReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller == null) { return false; }
+ if (controller == null) {
+ return false;
+ }
Card card = game.getCard(event.getTargetId());
- if (card == null) { return false; }
+ if (card == null) {
+ return false;
+ }
// TODO, deal with deprecated call
- if (controller.moveCardToExileWithInfo(card, source.getSourceId(), "Madness", source, game, ((ZoneChangeEvent) event).getFromZone(), true)) {
+ if (controller.moveCards(card, Zone.EXILED, source, game)) {
game.applyEffects(); // needed to add Madness ability to cards (e.g. by Falkenrath Gorger)
GameEvent gameEvent = new MadnessCardExiledEvent(card.getId(), source, controller.getId());
game.fireEvent(gameEvent);
@@ -190,13 +197,19 @@ class MadnessTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean resolve(Game game) {
- if (super.resolve(game)) { return true; }
+ if (super.resolve(game)) {
+ return true;
+ }
Card card = game.getCard(getSourceId());
- if (card == null) { return false; }
+ if (card == null) {
+ return false;
+ }
Player owner = game.getPlayer(card.getOwnerId());
- if (owner == null) { return false; }
+ if (owner == null) {
+ return false;
+ }
// if cast was not successfull, the card is moved to graveyard
owner.moveCards(card, Zone.GRAVEYARD, this, game);
@@ -205,7 +218,7 @@ class MadnessTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getTriggerPhrase() {
- return "When this card is exiled this way, " ;
+ return "When this card is exiled this way, ";
}
}
@@ -237,15 +250,21 @@ class MadnessCastEffect extends OneShotEffect {
}
@Override
- public MadnessCastEffect copy() { return new MadnessCastEffect(this); }
+ public MadnessCastEffect copy() {
+ return new MadnessCastEffect(this);
+ }
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getSourceId());
- if (card == null) { return false; }
+ if (card == null) {
+ return false;
+ }
Player owner = game.getPlayer(card.getOwnerId());
- if (owner == null) { return false; }
+ if (owner == null) {
+ return false;
+ }
// Replace with the new cost
SpellAbility castByMadness = card.getSpellAbility().copy();
@@ -268,9 +287,13 @@ enum MadnessCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
MageObject madnessSpell = game.getLastKnownInformation(source.getSourceId(), Zone.STACK, source.getSourceObjectZoneChangeCounter() - 1);
- if (!(madnessSpell instanceof Spell)) { return false; }
+ if (!(madnessSpell instanceof Spell)) {
+ return false;
+ }
- if (((Spell) madnessSpell).getSpellAbility() == null) { return false; }
+ if (((Spell) madnessSpell).getSpellAbility() == null) {
+ return false;
+ }
return ((Spell) madnessSpell).getSpellAbility().getSpellAbilityCastMode() == SpellAbilityCastMode.MADNESS;
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java
index f3a6c0f5f37..5898f19bba8 100644
--- a/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java
@@ -3,22 +3,21 @@ package mage.abilities.keyword;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
+import mage.cards.CardsImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.game.ExileZone;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell;
import mage.players.Player;
-
-import java.util.UUID;
-import mage.ApprovingObject;
+import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
/**
* This ability has no effect by default and will always return false on the
@@ -49,7 +48,7 @@ public class ReboundAbility extends SimpleStaticAbility {
super(Zone.STACK, new ReboundCastFromHandReplacementEffect());
}
- public ReboundAbility(ReboundAbility ability) {
+ public ReboundAbility(final ReboundAbility ability) {
super(ability);
}
@@ -57,18 +56,22 @@ public class ReboundAbility extends SimpleStaticAbility {
public ReboundAbility copy() {
return new ReboundAbility(this);
}
+
+ @Override
+ public String getRule() {
+ return "Rebound (If you cast this spell from your hand, "
+ + "exile it as it resolves. At the beginning of your next upkeep, "
+ + "you may cast this card from exile without paying its mana cost.)";
+ }
}
class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
ReboundCastFromHandReplacementEffect() {
super(Duration.WhileOnStack, Outcome.Benefit);
- this.staticText = "Rebound (If you cast this spell from your hand, "
- + "exile it as it resolves. At the beginning of your next upkeep, "
- + "you may cast this card from exile without paying its mana cost.)";
}
- ReboundCastFromHandReplacementEffect(ReboundCastFromHandReplacementEffect effect) {
+ private ReboundCastFromHandReplacementEffect(final ReboundCastFromHandReplacementEffect effect) {
super(effect);
}
@@ -84,17 +87,14 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
// by a spell like Cancel, or because all of its targets are illegal), rebound has no effect.
// The spell is simply put into your graveyard. You won’t get to cast it again next turn.
// (2010-06-15)
- if (((ZoneChangeEvent) event).getFromZone() == Zone.STACK
- && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
- && event.getSourceId() != null
- && event.getSourceId().equals(source.getSourceId())) { // if countered the source.sourceId is different or null if it fizzles
- Spell spell = game.getStack().getSpell(event.getTargetId());
- if (spell != null
- && spell.getFromZone() == Zone.HAND) {
- return true;
- }
- }
- return false;
+ if (((ZoneChangeEvent) event).getFromZone() != Zone.STACK
+ || ((ZoneChangeEvent) event).getToZone() != Zone.GRAVEYARD
+ || event.getSourceId() == null
+ || !event.getSourceId().equals(source.getSourceId())) {
+ return false;
+ } // if countered the source.sourceId is different or null if it fizzles
+ Spell spell = game.getStack().getSpell(event.getTargetId());
+ return spell != null && spell.getFromZone() == Zone.HAND;
}
@Override
@@ -102,23 +102,19 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
Spell sourceSpell = game.getStack().getSpell(source.getSourceId());
if (sourceSpell != null && sourceSpell.isCopy()) {
return false;
- } else {
- Card sourceCard = game.getCard(source.getSourceId());
- if (sourceCard != null) {
- Player player = game.getPlayer(sourceCard.getOwnerId());
- if (player != null) {
- // Add the delayed triggered effect
- ReboundEffectCastFromExileDelayedTrigger trigger
- = new ReboundEffectCastFromExileDelayedTrigger(source.getSourceId(), source.getSourceId());
- game.addDelayedTriggeredAbility(trigger, source);
-
- player.moveCardToExileWithInfo(sourceCard, sourceCard.getId(),
- player.getName() + " Rebound", source, game, Zone.STACK, true);
- return true;
- }
- }
}
- return false;
+ Card sourceCard = game.getCard(source.getSourceId());
+ if (sourceCard == null) {
+ return false;
+ }
+ Player player = game.getPlayer(sourceCard.getOwnerId());
+ if (player == null) {
+ return false;
+ }
+ // Add the delayed triggered effect
+ player.moveCardsToExile(sourceCard, source, game, true, null, "Rebound");
+ game.addDelayedTriggeredAbility(new ReboundEffectCastFromExileDelayedTrigger(sourceCard, game), source);
+ return true;
}
@Override
@@ -130,13 +126,11 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
- ReboundEffectCastFromExileDelayedTrigger(UUID cardId, UUID sourceId) {
- super(new ReboundCastSpellFromExileEffect());
- setSourceId(sourceId); // TODO: WTF?!
- this.optional = true;
+ ReboundEffectCastFromExileDelayedTrigger(Card card, Game game) {
+ super(new ReboundCastSpellFromExileEffect().setTargetPointer(new FixedTarget(card, game)), Duration.Custom, true, true);
}
- ReboundEffectCastFromExileDelayedTrigger(ReboundEffectCastFromExileDelayedTrigger ability) {
+ private ReboundEffectCastFromExileDelayedTrigger(final ReboundEffectCastFromExileDelayedTrigger ability) {
super(ability);
}
@@ -152,7 +146,7 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return MyTurnCondition.instance.apply(game, this);
+ return game.isActivePlayer(getControllerId());
}
@Override
@@ -169,41 +163,25 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility {
*/
class ReboundCastSpellFromExileEffect extends OneShotEffect {
- private static String castFromExileText = "Rebound - You may cast {this} "
- + "from exile without paying its mana cost";
-
ReboundCastSpellFromExileEffect() {
super(Outcome.PlayForFree);
- staticText = castFromExileText;
}
- ReboundCastSpellFromExileEffect(ReboundCastSpellFromExileEffect effect) {
+ private ReboundCastSpellFromExileEffect(final ReboundCastSpellFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
- ExileZone zone = game.getExile().getExileZone(source.getSourceId());
- if (zone == null
- || zone.isEmpty()) {
- return false;
- }
- Card reboundCard = zone.get(source.getSourceId(), game);
Player player = game.getPlayer(source.getControllerId());
- if (player != null
- && reboundCard != null) {
- game.getState().setValue("PlayFromNotOwnHandZone" + reboundCard.getId(), Boolean.TRUE);
- Boolean cardWasCast = player.cast(player.chooseAbilityForCast(reboundCard, game, true),
- game, true, new ApprovingObject(source, game));
- game.getState().setValue("PlayFromNotOwnHandZone" + reboundCard.getId(), null);
- return cardWasCast;
- }
- return false;
+ Card reboundCard = game.getCard(getTargetPointer().getFirst(game, source));
+ return player != null && reboundCard != null && CardUtil.castSpellWithAttributesForFree(
+ player, source, game, new CardsImpl(reboundCard), StaticFilters.FILTER_CARD
+ );
}
@Override
public ReboundCastSpellFromExileEffect copy() {
return new ReboundCastSpellFromExileEffect(this);
}
-
}