From 0c2abc69de1af847ef95994eb218a0ecd5afe4cd Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 25 Dec 2015 11:04:46 +0100 Subject: [PATCH] * Fixed some cost classes that didn't hadle correctly if a cost concerning card movement is paid or not. --- .../sets/darksteel/SteelshaperApprentice.java | 4 +- .../sets/dragonsmaze/KrasisIncubation.java | 4 +- .../src/mage/sets/dragonsmaze/MazesEnd.java | 4 +- .../mage/sets/exodus/RecurringNightmare.java | 4 +- .../sets/modernmasters/GrinningIgnus.java | 4 +- .../sets/saviorsofkamigawa/MoltingSkin.java | 4 +- .../src/mage/sets/tempest/BrokenFall.java | 4 +- .../src/mage/sets/urzassaga/Attunement.java | 4 +- .../src/mage/sets/visions/GossamerChains.java | 4 +- .../sets/zendikar/MagosiTheWaterveil.java | 4 +- .../costs/common/ExileFromGraveCost.java | 36 +++++++++-------- .../costs/common/ExileFromHandCost.java | 39 +++++++++++-------- .../costs/common/ExileFromStackCost.java | 25 ++++++------ .../common/ExileFromTopOfLibraryCost.java | 9 ++--- ...OpponentsCardFromExileToGraveyardCost.java | 2 +- .../costs/common/ExileSourceCost.java | 34 +++++++++------- .../common/ExileSourceFromGraveCost.java | 18 +++++---- .../costs/common/ExileXFromYourGraveCost.java | 9 ++--- ...rnToHandChosenControlledPermanentCost.java | 9 ++++- ...eturnToHandFromBattlefieldSourceCost.java} | 22 ++++++----- .../common/ReturnToHandFromGraveyardCost.java | 10 ++++- 21 files changed, 141 insertions(+), 112 deletions(-) rename Mage/src/main/java/mage/abilities/costs/common/{ReturnToHandSourceCost.java => ReturnToHandFromBattlefieldSourceCost.java} (78%) diff --git a/Mage.Sets/src/mage/sets/darksteel/SteelshaperApprentice.java b/Mage.Sets/src/mage/sets/darksteel/SteelshaperApprentice.java index f45923cdddb..64c4419ac17 100644 --- a/Mage.Sets/src/mage/sets/darksteel/SteelshaperApprentice.java +++ b/Mage.Sets/src/mage/sets/darksteel/SteelshaperApprentice.java @@ -37,7 +37,7 @@ import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ColoredManaCost; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; @@ -73,7 +73,7 @@ public class SteelshaperApprentice extends CardImpl { new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, filter), true), new ColoredManaCost(ColoredManaSymbol.W)); ability.addCost(new TapSourceCost()); - ability.addCost(new ReturnToHandSourceCost()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/KrasisIncubation.java b/Mage.Sets/src/mage/sets/dragonsmaze/KrasisIncubation.java index 911de590b06..b03a22ec227 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/KrasisIncubation.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/KrasisIncubation.java @@ -35,7 +35,7 @@ import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.combat.CantBlockAttackActivateAttachedEffect; @@ -71,7 +71,7 @@ public class KrasisIncubation extends CardImpl { // {1}{G}{U}, Return Krasis Incubation to its owner's hand: Put two +1/+1 counters on enchanted creature. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddPlusOneCountersAttachedEffect(2), new ManaCostsImpl("{1}{G}{U}")); - ability.addCost(new ReturnToHandSourceCost()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/MazesEnd.java b/Mage.Sets/src/mage/sets/dragonsmaze/MazesEnd.java index 3fb9802f9e3..ac77c6e4c0a 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/MazesEnd.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/MazesEnd.java @@ -38,7 +38,7 @@ import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -79,7 +79,7 @@ public class MazesEnd extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterCard)), new GenericManaCost(3)); ability.addEffect(new MazesEndEffect()); ability.addCost(new TapSourceCost()); - ability.addCost(new ReturnToHandSourceCost()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/exodus/RecurringNightmare.java b/Mage.Sets/src/mage/sets/exodus/RecurringNightmare.java index 200cbf81999..ebd86b04d1d 100644 --- a/Mage.Sets/src/mage/sets/exodus/RecurringNightmare.java +++ b/Mage.Sets/src/mage/sets/exodus/RecurringNightmare.java @@ -30,7 +30,7 @@ package mage.sets.exodus; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.cards.CardImpl; @@ -58,7 +58,7 @@ public class RecurringNightmare extends CardImpl { // Sacrifice a creature, Return Recurring Nightmare to its owner's hand: Return target creature card from your graveyard to the battlefield. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter2))); ability.addTarget(new TargetCardInYourGraveyard(filter)); - ability.addCost(new ReturnToHandSourceCost()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/modernmasters/GrinningIgnus.java b/Mage.Sets/src/mage/sets/modernmasters/GrinningIgnus.java index 3d239e84e5c..f9c3f1ae041 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/GrinningIgnus.java +++ b/Mage.Sets/src/mage/sets/modernmasters/GrinningIgnus.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.mana.ActivateAsSorceryManaAbility; import mage.cards.CardImpl; @@ -55,7 +55,7 @@ public class GrinningIgnus extends CardImpl { // {R}, Return Grinning Ignus to its owner's hand: Add {C}{C}{R} to your mana pool. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryManaAbility(Zone.BATTLEFIELD, new Mana(1, 0, 0, 0, 0, 2, 0), new ManaCostsImpl("{R}")); - ability.addCost(new ReturnToHandSourceCost()); + ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoltingSkin.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoltingSkin.java index e5def0d4249..f023a36006b 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoltingSkin.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoltingSkin.java @@ -33,7 +33,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.effects.common.RegenerateTargetEffect; import mage.cards.CardImpl; import mage.constants.Zone; @@ -50,7 +50,7 @@ public class MoltingSkin extends CardImpl { this.expansionSetCode = "SOK"; // Return Molting Skin to its owner's hand: Regenerate target creature. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ReturnToHandSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ReturnToHandFromBattlefieldSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/tempest/BrokenFall.java b/Mage.Sets/src/mage/sets/tempest/BrokenFall.java index da96953dc56..95db4c47494 100644 --- a/Mage.Sets/src/mage/sets/tempest/BrokenFall.java +++ b/Mage.Sets/src/mage/sets/tempest/BrokenFall.java @@ -33,7 +33,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.effects.common.RegenerateTargetEffect; import mage.cards.CardImpl; import mage.constants.Zone; @@ -49,7 +49,7 @@ public class BrokenFall extends CardImpl { super(ownerId, 110, "Broken Fall", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); this.expansionSetCode = "TMP"; - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ReturnToHandSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ReturnToHandFromBattlefieldSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/urzassaga/Attunement.java b/Mage.Sets/src/mage/sets/urzassaga/Attunement.java index 6fdbe0c8437..edd92c8c701 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Attunement.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Attunement.java @@ -32,7 +32,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; @@ -49,7 +49,7 @@ public class Attunement extends CardImpl { // Return Attunement to its owner's hand: Draw three cards, then discard four cards. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ReturnToHandSourceCost()); + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ReturnToHandFromBattlefieldSourceCost()); ability.addEffect(new DiscardControllerEffect(4)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/visions/GossamerChains.java b/Mage.Sets/src/mage/sets/visions/GossamerChains.java index aa991ac8fd6..3ef34f24ff2 100644 --- a/Mage.Sets/src/mage/sets/visions/GossamerChains.java +++ b/Mage.Sets/src/mage/sets/visions/GossamerChains.java @@ -30,7 +30,7 @@ package mage.sets.visions; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.effects.common.PreventDamageByTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -58,7 +58,7 @@ public class GossamerChains extends CardImpl { this.expansionSetCode = "VIS"; // Return Gossamer Chains to its owner's hand: Prevent all combat damage that would be dealt by target unblocked creature this turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageByTargetEffect(Duration.EndOfTurn, true), new ReturnToHandSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageByTargetEffect(Duration.EndOfTurn, true), new ReturnToHandFromBattlefieldSourceCost()); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/zendikar/MagosiTheWaterveil.java b/Mage.Sets/src/mage/sets/zendikar/MagosiTheWaterveil.java index 6850c94e1c8..0c42f748e97 100644 --- a/Mage.Sets/src/mage/sets/zendikar/MagosiTheWaterveil.java +++ b/Mage.Sets/src/mage/sets/zendikar/MagosiTheWaterveil.java @@ -32,7 +32,7 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; -import mage.abilities.costs.common.ReturnToHandSourceCost; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.counter.AddCountersSourceEffect; @@ -70,7 +70,7 @@ public class MagosiTheWaterveil extends CardImpl { // {T}, Remove an eon counter from Magosi, the Waterveil and return it to its owner's hand: Take an extra turn after this one. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddExtraTurnControllerEffect(), new TapSourceCost()); ability2.addCost(new RemoveCountersSourceCost(CounterType.EON.createInstance())); - ability2.addCost(new ReturnToHandSourceCost()); + ability2.addCost(new ReturnToHandFromBattlefieldSourceCost()); this.addAbility(ability2); } diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java index 3c098074ca4..7ad275dfa39 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.ArrayList; @@ -34,6 +33,8 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -53,18 +54,17 @@ public class ExileFromGraveCost extends CostImpl { public ExileFromGraveCost(TargetCardInYourGraveyard target) { this.addTarget(target); if (target.getMaxNumberOfTargets() > 1) { - this.text = "Exile " + - (target.getNumberOfTargets() == 1 && target.getMaxNumberOfTargets() == Integer.MAX_VALUE ? "one or more" : - ((target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to ":"")) + - CardUtil.numberToText(target.getMaxNumberOfTargets())) + - " " + target.getTargetName(); - } - else { + this.text = "Exile " + + (target.getNumberOfTargets() == 1 && target.getMaxNumberOfTargets() == Integer.MAX_VALUE ? "one or more" + : ((target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to " : "")) + + CardUtil.numberToText(target.getMaxNumberOfTargets())) + + " " + target.getTargetName(); + } else { this.text = "Exile " + target.getTargetName(); } if (!this.text.endsWith(" from your graveyard")) { this.text = this.text + " from your graveyard"; - } + } } public ExileFromGraveCost(TargetCardInYourGraveyard target, String text) { @@ -77,7 +77,6 @@ public class ExileFromGraveCost extends CostImpl { this.text = "Exile " + target.getTargetName(); } - public ExileFromGraveCost(final ExileFromGraveCost cost) { super(cost); this.exiledCards.addAll(cost.getExiledCards()); @@ -88,15 +87,18 @@ public class ExileFromGraveCost extends CostImpl { Player controller = game.getPlayer(controllerId); if (controller != null) { if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) { - for (UUID targetId: targets.get(0).getTargets()) { + for (UUID targetId : targets.get(0).getTargets()) { Card card = game.getCard(targetId); if (card == null || !game.getState().getZone(targetId).equals(Zone.GRAVEYARD)) { return false; } exiledCards.add(card); - paid |= controller.moveCardToExileWithInfo(card, null, null, sourceId, game, Zone.GRAVEYARD, true); } } + Cards cardsToExile = new CardsImpl(); + cardsToExile.addAll(exiledCards); + controller.moveCards(cardsToExile, Zone.EXILED, ability, game); + paid = true; } return paid; diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromHandCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromHandCost.java index 3ca78553cac..6f696804f85 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromHandCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromHandCost.java @@ -25,17 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; - + import java.util.ArrayList; import java.util.List; import java.util.UUID; -import mage.Mana; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.abilities.costs.mana.VariableManaCost; import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -47,47 +47,52 @@ import mage.target.common.TargetCardInHand; * @author LevelX2 */ public class ExileFromHandCost extends CostImpl { - + List cards = new ArrayList<>(); private boolean setXFromCMC; - + public ExileFromHandCost(TargetCardInHand target) { this(target, false); } + /** - * + * * @param target - * @param setXFromCMC the spells X value on the stack is set to the converted mana costs of the exiled card + * @param setXFromCMC the spells X value on the stack is set to the + * converted mana costs of the exiled card */ public ExileFromHandCost(TargetCardInHand target, boolean setXFromCMC) { this.addTarget(target); this.text = "exile " + target.getTargetName(); this.setXFromCMC = setXFromCMC; } - + public ExileFromHandCost(final ExileFromHandCost cost) { super(cost); - for (Card card: cost.cards) { + for (Card card : cost.cards) { this.cards.add(card.copy()); } this.setXFromCMC = cost.setXFromCMC; } - + @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) { Player player = game.getPlayer(controllerId); int cmc = 0; - for (UUID targetId: targets.get(0).getTargets()) { + for (UUID targetId : targets.get(0).getTargets()) { Card card = player.getHand().get(targetId, game); if (card == null) { return false; } cmc += card.getManaCost().convertedManaCost(); this.cards.add(card); - paid |= player.moveCardToExileWithInfo(card, null, null, ability.getSourceId(), game, Zone.HAND, true); } - if (paid && setXFromCMC) { + Cards cardsToExile = new CardsImpl(); + cardsToExile.addAll(cards); + player.moveCards(cardsToExile, Zone.EXILED, ability, game); + paid = true; + if (setXFromCMC) { VariableManaCost vmc = new VariableManaCost(); vmc.setAmount(cmc); vmc.setPaid(); @@ -96,18 +101,18 @@ public class ExileFromHandCost extends CostImpl { } return paid; } - + @Override public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { return targets.canChoose(sourceId, controllerId, game); } - + @Override public ExileFromHandCost copy() { return new ExileFromHandCost(this); } - - public List getCards() { + + public List getCards() { return cards; } } diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java index 64f9c36d72e..ec143a97e72 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java @@ -25,11 +25,9 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; - -import java.util.UUID; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.constants.Outcome; @@ -37,45 +35,46 @@ import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; import mage.target.TargetSpell; - + /** * * @author LevelX2 */ public class ExileFromStackCost extends CostImpl { - + public ExileFromStackCost(TargetSpell target) { this.addTarget(target); this.text = "Exile " + target.getTargetName(); } - + public ExileFromStackCost(ExileFromStackCost cost) { super(cost); } - + @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) { Player player = game.getPlayer(controllerId); - for (UUID targetId: targets.get(0).getTargets()) { + for (UUID targetId : targets.get(0).getTargets()) { Spell spellToExile = game.getStack().getSpell(targetId); if (spellToExile == null) { return false; } - paid |= spellToExile.moveToExile(null, "", ability.getSourceId(), game); - if (paid && !game.isSimulation()) { - game.informPlayers(player.getLogName() + " exiles " + spellToExile.getName() +" (as costs)"); + spellToExile.moveToExile(null, "", ability.getSourceId(), game); + paid = true; + if (!game.isSimulation()) { + game.informPlayers(player.getLogName() + " exiles " + spellToExile.getName() + " (as costs)"); } } } return paid; } - + @Override public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { return targets.canChoose(controllerId, game); } - + @Override public ExileFromStackCost copy() { return new ExileFromStackCost(this); diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromTopOfLibraryCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromTopOfLibraryCost.java index 02620418756..cee479c6fd7 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromTopOfLibraryCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromTopOfLibraryCost.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; @@ -47,7 +46,7 @@ public class ExileFromTopOfLibraryCost extends CostImpl { public ExileFromTopOfLibraryCost(int amount) { this.amount = amount; this.text = "Exile the top " + (amount == 1 ? "card" : CardUtil.numberToText(amount) + " cards") - + " of your library"; + + " of your library"; } public ExileFromTopOfLibraryCost(ExileFromTopOfLibraryCost cost) { @@ -58,7 +57,7 @@ public class ExileFromTopOfLibraryCost extends CostImpl { @Override public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { Player controller = game.getPlayer(controllerId); - if(controller == null) { + if (controller == null) { return false; } return controller.getLibrary().size() >= amount; @@ -67,8 +66,8 @@ public class ExileFromTopOfLibraryCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { Player controller = game.getPlayer(controllerId); - if(controller != null) { - controller.moveCards(controller.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.EXILED, ability, game); + if (controller != null) { + controller.moveCards(controller.getLibrary().getTopCards(game, amount), Zone.EXILED, ability, game); paid = true; } return paid; diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileOpponentsCardFromExileToGraveyardCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileOpponentsCardFromExileToGraveyardCost.java index 94e498b2e3d..061767a1124 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileOpponentsCardFromExileToGraveyardCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileOpponentsCardFromExileToGraveyardCost.java @@ -48,7 +48,7 @@ public class ExileOpponentsCardFromExileToGraveyardCost extends CostImpl { Card card = game.getCard(target.getFirstTarget()); if (card != null) { paid = true; - controller.moveCards(card, null, Zone.GRAVEYARD, ability, game); + controller.moveCards(card, Zone.GRAVEYARD, ability, game); } } } diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java index 0246273ad3e..8db34d265d8 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; @@ -45,14 +44,16 @@ import mage.util.CardUtil; public class ExileSourceCost extends CostImpl { private boolean toUniqueExileZone; - + public ExileSourceCost() { this.text = "Exile {this}"; } + /** - * - * @param toUniqueExileZone moves the card to a source object dependant unique exile zone, so another - * effect of the same source object (e.g. Deadeye Navigator) can identify the card + * + * @param toUniqueExileZone moves the card to a source object dependant + * unique exile zone, so another effect of the same source object (e.g. + * Deadeye Navigator) can identify the card */ public ExileSourceCost(boolean toUniqueExileZone) { this.text = "Exile {this}"; @@ -68,14 +69,19 @@ public class ExileSourceCost extends CostImpl { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { MageObject sourceObject = ability.getSourceObject(game); Player controller = game.getPlayer(controllerId); - if (controller != null && sourceObject != null && (sourceObject instanceof Card)) { + if (controller != null && sourceObject != null && (sourceObject instanceof Card)) { UUID exileZoneId = null; String exileZoneName = ""; if (toUniqueExileZone) { exileZoneId = CardUtil.getExileZoneId(game, ability.getSourceId(), ability.getSourceObjectZoneChangeCounter()); - exileZoneName = sourceObject.getName(); - } - paid = controller.moveCardToExileWithInfo((Card) sourceObject, exileZoneId, exileZoneName, sourceId, game, game.getState().getZone(sourceObject.getId()), true); + exileZoneName = sourceObject.getName(); + } + controller.moveCardToExileWithInfo((Card) sourceObject, exileZoneId, exileZoneName, sourceId, game, game.getState().getZone(sourceObject.getId()), 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; } return paid; } 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 1448b9df09c..ff72d067267 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceFromGraveCost.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; @@ -56,7 +55,12 @@ public class ExileSourceFromGraveCost extends CostImpl { if (controller != null) { Card card = game.getCard(sourceId); if (card != null && game.getState().getZone(sourceId).equals(Zone.GRAVEYARD)) { - paid = controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.GRAVEYARD, true); + controller.moveCardToExileWithInfo(card, null, "", sourceId, 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; } } return paid; diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileXFromYourGraveCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileXFromYourGraveCost.java index 37a22d6a81d..b8d7d0b24fc 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileXFromYourGraveCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileXFromYourGraveCost.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import mage.abilities.Ability; @@ -40,8 +39,7 @@ import mage.target.common.TargetCardInYourGraveyard; * * @author LevelX2 */ - -public class ExileXFromYourGraveCost extends VariableCostImpl { +public class ExileXFromYourGraveCost extends VariableCostImpl { protected FilterCard filter; @@ -50,10 +48,9 @@ public class ExileXFromYourGraveCost extends VariableCostImpl { } public ExileXFromYourGraveCost(FilterCard filter, boolean additionalCostText) { - super(new StringBuilder(filter.getMessage()).append(" to exile").toString()); + super(filter.getMessage() + " to exile"); this.filter = filter; - this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, exile ":"Exile ") - .append(xText).append(" ").append(filter.getMessage()).toString(); + this.text = (additionalCostText ? "As an additional cost to cast {source}, exile " : "Exile ") + xText + " " + filter.getMessage(); } public ExileXFromYourGraveCost(final ExileXFromYourGraveCost cost) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java index 238377fdf4b..2366e9d7dfe 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java @@ -27,10 +27,14 @@ */ package mage.abilities.costs.common; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; +import mage.cards.Card; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -61,13 +65,16 @@ public class ReturnToHandChosenControlledPermanentCost extends CostImpl { Player controller = game.getPlayer(controllerId); if (controller != null) { if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) { + Set permanentsToReturn = new HashSet<>(); for (UUID targetId : targets.get(0).getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent == null) { return false; } - paid |= controller.moveCardToHandWithInfo(permanent, sourceId, game); + permanentsToReturn.add((Card) permanent); } + controller.moveCards(permanentsToReturn, Zone.HAND, ability, game); + paid = true; } } return paid; diff --git a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromBattlefieldSourceCost.java similarity index 78% rename from Mage/src/main/java/mage/abilities/costs/common/ReturnToHandSourceCost.java rename to Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromBattlefieldSourceCost.java index 43ee14395ba..5f4d4c6396a 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromBattlefieldSourceCost.java @@ -25,36 +25,38 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import java.util.UUID; - -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; /** * @author Loki */ -public class ReturnToHandSourceCost extends CostImpl { +public class ReturnToHandFromBattlefieldSourceCost extends CostImpl { - public ReturnToHandSourceCost() { + public ReturnToHandFromBattlefieldSourceCost() { this.text = "return {this} to its owner's hand"; } - public ReturnToHandSourceCost(ReturnToHandSourceCost cost) { + public ReturnToHandFromBattlefieldSourceCost(ReturnToHandFromBattlefieldSourceCost cost) { super(cost); } @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { Permanent permanent = game.getPermanent(sourceId); - if (permanent == null) + Player controller = game.getPlayer(controllerId); + if (permanent == null || controller == null) { return false; - paid = permanent.moveToZone(Zone.HAND, sourceId, game, false); + } + controller.moveCards(permanent, Zone.HAND, ability, game); + paid = true; return paid; } @@ -64,7 +66,7 @@ public class ReturnToHandSourceCost extends CostImpl { } @Override - public ReturnToHandSourceCost copy() { - return new ReturnToHandSourceCost(this); + public ReturnToHandFromBattlefieldSourceCost copy() { + return new ReturnToHandFromBattlefieldSourceCost(this); } } diff --git a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java index 48dc5dcdadb..e12103dc964 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ReturnToHandFromGraveyardCost.java @@ -27,10 +27,14 @@ */ package mage.abilities.costs.common; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; +import mage.cards.Card; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; @@ -59,14 +63,18 @@ public class ReturnToHandFromGraveyardCost extends CostImpl { Player controller = game.getPlayer(controllerId); if (controller != null) { if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) { + Set cardsToMove = new LinkedHashSet<>(); for (UUID targetId : targets.get(0).getTargets()) { mage.cards.Card targetCard = game.getCard(targetId); if (targetCard == null) { return false; } - paid |= controller.moveCardToHandWithInfo(targetCard, sourceId, game); + cardsToMove.add(targetCard); } + controller.moveCards(cardsToMove, Zone.HAND, ability, game); + paid = true; } + } return paid; }