From a3bc45279519c6421b18f33b9de6c1fd0e9dbe86 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 30 Jul 2015 16:13:27 +0200 Subject: [PATCH] Added Gustcloak Savior, Spurnmage Advocate and Gleancrawler; --- .../mage/sets/commander/BrionStoutarm.java | 11 +- .../sets/commander/SpurnmageAdvocate.java | 87 ++++++++++++ .../sets/elspethvskiora/GustcloakSavior.java | 52 ++++++++ .../sets/izzetvsgolgari/Gleancrawler.java | 54 ++++++++ .../mage/sets/judgment/SpurnmageAdvocate.java | 52 ++++++++ .../src/mage/sets/magic2014/GrimReturn.java | 8 +- .../mage/sets/onslaught/GustcloakSavior.java | 85 ++++++++++++ .../sets/prereleaseevents/Gleancrawler.java | 125 ++++++++++++++++++ .../src/mage/sets/ravnica/Gleancrawler.java | 54 ++++++++ .../sets/shadowmoor/TwilightShepherd.java | 31 +++-- .../src/mage/sets/zendikar/RavenousTrap.java | 15 +-- .../java/org/mage/test/player/TestPlayer.java | 15 +++ .../BecomesBlockedAllTriggeredAbility.java | 9 +- .../effects/common/DestroyTargetEffect.java | 81 ++++++------ .../common/RemoveFromCombatTargetEffect.java | 69 +++++----- .../common/ReturnToHandTargetEffect.java | 52 +++----- Mage/src/mage/players/Player.java | 8 +- Mage/src/mage/players/PlayerImpl.java | 29 ++-- .../common/CardsPutIntoGraveyardWatcher.java | 18 ++- 19 files changed, 692 insertions(+), 163 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/commander/SpurnmageAdvocate.java create mode 100644 Mage.Sets/src/mage/sets/elspethvskiora/GustcloakSavior.java create mode 100644 Mage.Sets/src/mage/sets/izzetvsgolgari/Gleancrawler.java create mode 100644 Mage.Sets/src/mage/sets/judgment/SpurnmageAdvocate.java create mode 100644 Mage.Sets/src/mage/sets/onslaught/GustcloakSavior.java create mode 100644 Mage.Sets/src/mage/sets/prereleaseevents/Gleancrawler.java create mode 100644 Mage.Sets/src/mage/sets/ravnica/Gleancrawler.java diff --git a/Mage.Sets/src/mage/sets/commander/BrionStoutarm.java b/Mage.Sets/src/mage/sets/commander/BrionStoutarm.java index 7443a670474..f500c52af55 100644 --- a/Mage.Sets/src/mage/sets/commander/BrionStoutarm.java +++ b/Mage.Sets/src/mage/sets/commander/BrionStoutarm.java @@ -76,7 +76,7 @@ public class BrionStoutarm extends CardImpl { // {R}, {tap}, Sacrifice a creature other than Brion Stoutarm: Brion Stoutarm deals damage equal to the sacrificed creature's power to target player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BrionStoutarmEffect(), new ManaCostsImpl("{R}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, true))); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } @@ -110,9 +110,9 @@ class BrionStoutarmEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int amount = 0; - for (Cost cost: source.getCosts()) { - if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost)cost).getPermanents().size() > 0) { - amount = ((SacrificeTargetCost)cost).getPermanents().get(0).getPower().getValue(); + for (Cost cost : source.getCosts()) { + if (cost instanceof SacrificeTargetCost && ((SacrificeTargetCost) cost).getPermanents().size() > 0) { + amount = ((SacrificeTargetCost) cost).getPermanents().get(0).getPower().getValue(); break; } } @@ -120,9 +120,8 @@ class BrionStoutarmEffect extends OneShotEffect { Player player = game.getPlayer(source.getFirstTarget()); if (player != null) { player.damage(amount, source.getSourceId(), game, false, true); - return true; } } - return false; + return true; } } diff --git a/Mage.Sets/src/mage/sets/commander/SpurnmageAdvocate.java b/Mage.Sets/src/mage/sets/commander/SpurnmageAdvocate.java new file mode 100644 index 00000000000..2391cab356a --- /dev/null +++ b/Mage.Sets/src/mage/sets/commander/SpurnmageAdvocate.java @@ -0,0 +1,87 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.commander; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.other.OwnerPredicate; +import mage.target.common.TargetAttackingCreature; +import mage.target.common.TargetCardInASingleGraveyard; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author LevelX2 + */ +public class SpurnmageAdvocate extends CardImpl { + + private static final FilterCard filter = new FilterCard("two target cards from an opponent's graveyard"); + + static { + filter.add(new OwnerPredicate(TargetController.OPPONENT)); + } + + public SpurnmageAdvocate(UUID ownerId) { + super(ownerId, 33, "Spurnmage Advocate", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{W}"); + this.expansionSetCode = "CMD"; + this.subtype.add("Human"); + this.subtype.add("Nomad"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {T}: Return two target cards from an opponent's graveyard to his or her hand. Destroy target attacking creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new TapSourceCost()); + ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter)); + Effect effect = new DestroyTargetEffect(); + effect.setTargetPointer(new SecondTargetPointer()); + ability.addEffect(effect); + ability.addTarget(new TargetAttackingCreature()); + this.addAbility(ability); + } + + public SpurnmageAdvocate(final SpurnmageAdvocate card) { + super(card); + } + + @Override + public SpurnmageAdvocate copy() { + return new SpurnmageAdvocate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/elspethvskiora/GustcloakSavior.java b/Mage.Sets/src/mage/sets/elspethvskiora/GustcloakSavior.java new file mode 100644 index 00000000000..0a8b9bbc2fd --- /dev/null +++ b/Mage.Sets/src/mage/sets/elspethvskiora/GustcloakSavior.java @@ -0,0 +1,52 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.elspethvskiora; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class GustcloakSavior extends mage.sets.onslaught.GustcloakSavior { + + public GustcloakSavior(UUID ownerId) { + super(ownerId); + this.cardNumber = 11; + this.expansionSetCode = "DDO"; + } + + public GustcloakSavior(final GustcloakSavior card) { + super(card); + } + + @Override + public GustcloakSavior copy() { + return new GustcloakSavior(this); + } +} diff --git a/Mage.Sets/src/mage/sets/izzetvsgolgari/Gleancrawler.java b/Mage.Sets/src/mage/sets/izzetvsgolgari/Gleancrawler.java new file mode 100644 index 00000000000..79b57a8c2f4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/izzetvsgolgari/Gleancrawler.java @@ -0,0 +1,54 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.izzetvsgolgari; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class Gleancrawler extends mage.sets.prereleaseevents.Gleancrawler { + + public Gleancrawler(UUID ownerId) { + super(ownerId); + this.cardNumber = 64; + this.expansionSetCode = "DDJ"; + this.rarity = Rarity.RARE; + } + + public Gleancrawler(final Gleancrawler card) { + super(card); + } + + @Override + public Gleancrawler copy() { + return new Gleancrawler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/judgment/SpurnmageAdvocate.java b/Mage.Sets/src/mage/sets/judgment/SpurnmageAdvocate.java new file mode 100644 index 00000000000..7ac6d852660 --- /dev/null +++ b/Mage.Sets/src/mage/sets/judgment/SpurnmageAdvocate.java @@ -0,0 +1,52 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.judgment; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class SpurnmageAdvocate extends mage.sets.commander.SpurnmageAdvocate { + + public SpurnmageAdvocate(UUID ownerId) { + super(ownerId); + this.cardNumber = 27; + this.expansionSetCode = "JUD"; + } + + public SpurnmageAdvocate(final SpurnmageAdvocate card) { + super(card); + } + + @Override + public SpurnmageAdvocate copy() { + return new SpurnmageAdvocate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magic2014/GrimReturn.java b/Mage.Sets/src/mage/sets/magic2014/GrimReturn.java index 0a93db0e9f8..ef9a63a835f 100644 --- a/Mage.Sets/src/mage/sets/magic2014/GrimReturn.java +++ b/Mage.Sets/src/mage/sets/magic2014/GrimReturn.java @@ -30,6 +30,7 @@ package mage.sets.magic2014; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; @@ -56,7 +57,6 @@ public class GrimReturn extends CardImpl { super(ownerId, 100, "Grim Return", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{B}"); this.expansionSetCode = "M14"; - // Choose target creature card in a graveyard that was put there from the battlefield this turn. Put that card onto the battlefield under your control. Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Choose target creature card in a graveyard that was put there from the battlefield this turn. Put that card onto the battlefield under your control"); @@ -80,8 +80,10 @@ public class GrimReturn extends CardImpl { if (watcher != null) { FilterCard filter = new FilterCreatureCard(textFilter); List uuidPredicates = new ArrayList<>(); - for (UUID uuid :watcher.getCardsPutToGraveyardFromBattlefield()) { - uuidPredicates.add(new CardIdPredicate(uuid)); + for (MageObjectReference mor : watcher.getCardsPutToGraveyardFromBattlefield()) { + if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { + uuidPredicates.add(new CardIdPredicate(mor.getSourceId())); + } } filter.add(Predicates.or(uuidPredicates)); ability.getTargets().clear(); diff --git a/Mage.Sets/src/mage/sets/onslaught/GustcloakSavior.java b/Mage.Sets/src/mage/sets/onslaught/GustcloakSavior.java new file mode 100644 index 00000000000..c6b4892ca19 --- /dev/null +++ b/Mage.Sets/src/mage/sets/onslaught/GustcloakSavior.java @@ -0,0 +1,85 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.onslaught; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesBlockedAllTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class GustcloakSavior extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public GustcloakSavior(UUID ownerId) { + super(ownerId, 36, "Gustcloak Savior", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.expansionSetCode = "ONS"; + this.subtype.add("Bird"); + this.subtype.add("Soldier"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever a creature you control becomes blocked, you may untap that creature and remove it from combat. + Effect effect = new UntapTargetEffect(); + effect.setText("you may untap that creature"); + Ability ability = new BecomesBlockedAllTriggeredAbility(effect, true, filter, true); + effect = new RemoveFromCombatTargetEffect(); + effect.setText("and remove it from combat"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public GustcloakSavior(final GustcloakSavior card) { + super(card); + } + + @Override + public GustcloakSavior copy() { + return new GustcloakSavior(this); + } +} diff --git a/Mage.Sets/src/mage/sets/prereleaseevents/Gleancrawler.java b/Mage.Sets/src/mage/sets/prereleaseevents/Gleancrawler.java new file mode 100644 index 00000000000..d3deaada3ad --- /dev/null +++ b/Mage.Sets/src/mage/sets/prereleaseevents/Gleancrawler.java @@ -0,0 +1,125 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.prereleaseevents; + +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.CardsPutIntoGraveyardWatcher; + +/** + * + * @author LevelX2 + */ +public class Gleancrawler extends CardImpl { + + public Gleancrawler(UUID ownerId) { + super(ownerId, 27, "Gleancrawler", Rarity.SPECIAL, new CardType[]{CardType.CREATURE}, "{3}{B/G}{B/G}{B/G}"); + this.expansionSetCode = "PTC"; + this.subtype.add("Insect"); + this.subtype.add("Horror"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // ({B/G} can be paid with either {B} or {G}.) + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("({B/G} can be paid with either {B} or {G}.)"))); + // Trample + this.addAbility(TrampleAbility.getInstance()); + // At the beginning of your end step, return to your hand all creature cards in your graveyard that were put there from the battlefield this turn. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new GleancrawlerEffect(), TargetController.YOU, false), new CardsPutIntoGraveyardWatcher()); + + } + + public Gleancrawler(final Gleancrawler card) { + super(card); + } + + @Override + public Gleancrawler copy() { + return new Gleancrawler(this); + } +} + +class GleancrawlerEffect extends OneShotEffect { + + boolean applied = false; + + public GleancrawlerEffect() { + super(Outcome.ReturnToHand); + this.staticText = "return to your hand all creature cards in your graveyard that were put there from the battlefield this turn"; + } + + public GleancrawlerEffect(final GleancrawlerEffect effect) { + super(effect); + } + + @Override + public GleancrawlerEffect copy() { + return new GleancrawlerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get("CardsPutIntoGraveyardWatcher"); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && watcher != null) { + Set cardsToGraveyardThisTurn = watcher.getCardsPutToGraveyardFromBattlefield(); + Cards cardsToHand = new CardsImpl(); + for (MageObjectReference mor : cardsToGraveyardThisTurn) { + if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { + Card card = game.getCard(mor.getSourceId()); + if (card != null && card.getCardType().contains(CardType.CREATURE) + && card.getOwnerId().equals(source.getControllerId())) { + cardsToHand.add(card); + } + } + } + controller.moveCards(cardsToHand, Zone.GRAVEYARD, Zone.HAND, source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ravnica/Gleancrawler.java b/Mage.Sets/src/mage/sets/ravnica/Gleancrawler.java new file mode 100644 index 00000000000..fb84aee512e --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnica/Gleancrawler.java @@ -0,0 +1,54 @@ +/* + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.sets.ravnica; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class Gleancrawler extends mage.sets.prereleaseevents.Gleancrawler { + + public Gleancrawler(UUID ownerId) { + super(ownerId); + this.cardNumber = 247; + this.expansionSetCode = "RAV"; + this.rarity = Rarity.RARE; + } + + public Gleancrawler(final Gleancrawler card) { + super(card); + } + + @Override + public Gleancrawler copy() { + return new Gleancrawler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/TwilightShepherd.java b/Mage.Sets/src/mage/sets/shadowmoor/TwilightShepherd.java index 09f251c2d9c..94fc3a43426 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/TwilightShepherd.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/TwilightShepherd.java @@ -30,19 +30,23 @@ package mage.sets.shadowmoor; import java.util.Set; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.PersistAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.players.Player; import mage.watchers.common.CardsPutIntoGraveyardWatcher; /** @@ -104,17 +108,22 @@ class TwilightShepherdEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get("CardsPutIntoGraveyardWatcher"); - if (watcher != null) { - Set cardsInGraveyardId = watcher.getCardsPutToGraveyardFromBattlefield(); - for (UUID cardId : cardsInGraveyardId) { - Card card = game.getCard(cardId); - if (card != null - && card.getOwnerId().equals(source.getControllerId()) - && game.getState().getZone(card.getId()).match(Zone.GRAVEYARD)) { - applied = card.moveToZone(Zone.HAND, source.getSourceId(), game, false); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && watcher != null) { + Set cardsInGraveyard = watcher.getCardsPutToGraveyardFromBattlefield(); + Cards cardsToHand = new CardsImpl(); + for (MageObjectReference mor : cardsInGraveyard) { + if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { + Card card = game.getCard(mor.getSourceId()); + if (card != null + && card.getOwnerId().equals(source.getControllerId())) { + cardsToHand.add(card); + } } } + controller.moveCards(cardsToHand, Zone.GRAVEYARD, Zone.HAND, source, game); + return true; } - return applied; + return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/zendikar/RavenousTrap.java b/Mage.Sets/src/mage/sets/zendikar/RavenousTrap.java index d01bf7f2758..f21710f496f 100644 --- a/Mage.Sets/src/mage/sets/zendikar/RavenousTrap.java +++ b/Mage.Sets/src/mage/sets/zendikar/RavenousTrap.java @@ -27,21 +27,15 @@ */ package mage.sets.zendikar; -import java.util.ArrayList; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostImpl; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileGraveyardAllTargetPlayerEffect; import mage.cards.CardImpl; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.game.Game; -import mage.players.Player; import mage.target.TargetPlayer; import mage.watchers.common.CardsPutIntoGraveyardWatcher; @@ -56,7 +50,6 @@ public class RavenousTrap extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Trap"); - // If an opponent had three or more cards put into his or her graveyard from anywhere this turn, you may pay {0} rather than pay Ravenous Trap's mana cost. this.getSpellAbility().addAlternativeCost( new RavenousTrapAlternativeCost()); @@ -97,7 +90,7 @@ class RavenousTrapAlternativeCost extends AlternativeCostImpl { public boolean isAvailable(Game game, Ability source) { CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get("CardsPutIntoGraveyardWatcher"); if (watcher != null) { - for (UUID opponentId: game.getOpponents(source.getControllerId())) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { if (watcher.getAmountCardsPutToGraveyard(opponentId) > 2) { return true; } @@ -108,6 +101,6 @@ class RavenousTrapAlternativeCost extends AlternativeCostImpl { @Override public String getText() { - return "If an opponent had three or more cards put into his or her graveyard from anywhere this turn, you may pay {0} rather than pay Ravenous Trap's mana cost"; + return "If an opponent had three or more cards put into his or her graveyard from anywhere this turn, you may pay {0} rather than pay {this}'s mana cost"; } } 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 4b8baa125c1..830c7af2a0c 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 @@ -1672,6 +1672,21 @@ public class TestPlayer implements Player { return computerPlayer.moveCards(cards, fromZone, toZone, source, game); } + @Override + public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { + return computerPlayer.moveCards(cards, fromZone, toZone, source, game); + } + + @Override + public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { + return computerPlayer.moveCards(card, fromZone, toZone, source, game); + } + + @Override + public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { + return computerPlayer.moveCards(cards, fromZone, toZone, source, game); + } + @Override public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) { return computerPlayer.moveCardToHandWithInfo(card, sourceId, game, fromZone); diff --git a/Mage/src/mage/abilities/common/BecomesBlockedAllTriggeredAbility.java b/Mage/src/mage/abilities/common/BecomesBlockedAllTriggeredAbility.java index 452b40bfadb..58a00f4543c 100644 --- a/Mage/src/mage/abilities/common/BecomesBlockedAllTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BecomesBlockedAllTriggeredAbility.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.common; import mage.abilities.TriggeredAbilityImpl; @@ -41,7 +40,6 @@ import mage.target.targetpointer.FixedTarget; * * @author LevelX2 */ - public class BecomesBlockedAllTriggeredAbility extends TriggeredAbilityImpl { private FilterCreaturePermanent filter; @@ -50,6 +48,7 @@ public class BecomesBlockedAllTriggeredAbility extends TriggeredAbilityImpl { public BecomesBlockedAllTriggeredAbility(Effect effect, boolean optional) { this(effect, optional, new FilterCreaturePermanent("a creature"), false); } + public BecomesBlockedAllTriggeredAbility(Effect effect, boolean optional, FilterCreaturePermanent filter, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); this.filter = filter; @@ -72,7 +71,7 @@ public class BecomesBlockedAllTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { if (setTargetPointer) { - for(Effect effect :this.getEffects()) { + for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); } } @@ -83,9 +82,7 @@ public class BecomesBlockedAllTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - StringBuilder sb = new StringBuilder("Whenever ").append(filter.getMessage()); - sb.append(" becomes blocked, ").append(super.getRule()); - return sb.toString(); + return "Whenever " + filter.getMessage() + " becomes blocked, " + super.getRule(); } @Override diff --git a/Mage/src/mage/abilities/effects/common/DestroyTargetEffect.java b/Mage/src/mage/abilities/effects/common/DestroyTargetEffect.java index c001d57ae29..9339079cb1f 100644 --- a/Mage/src/mage/abilities/effects/common/DestroyTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/DestroyTargetEffect.java @@ -1,31 +1,30 @@ /* -* 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 -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* 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. -*/ - + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.effects.common; import java.util.UUID; @@ -37,6 +36,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.targetpointer.FirstTargetPointer; +import mage.target.targetpointer.SecondTargetPointer; import mage.util.CardUtil; /** @@ -84,8 +84,7 @@ public class DestroyTargetEffect extends OneShotEffect { } } } - } - else if (targetPointer.getTargets(game, source).size() > 0) { + } else if (targetPointer.getTargets(game, source).size() > 0) { for (UUID permanentId : targetPointer.getTargets(game, source)) { Permanent permanent = game.getPermanent(permanentId); if (permanent != null) { @@ -105,15 +104,23 @@ public class DestroyTargetEffect extends OneShotEffect { StringBuilder sb = new StringBuilder(); if (mode.getTargets().size() == 0) { sb.append("destroy that creature"); //TODO add possibility to specify text with targetPointer usage - } else if (mode.getTargets().get(0).getNumberOfTargets() == 1) { - String targetName = mode.getTargets().get(0).getTargetName(); - sb.append("destroy "); - if (!targetName.startsWith("another")) { - sb.append("target "); - } - sb.append(targetName); } else { - sb.append("Destroy ").append(CardUtil.numberToText(mode.getTargets().get(0).getNumberOfTargets())).append(" target ").append(mode.getTargets().get(0).getTargetName()); + Target target; + if (targetPointer instanceof SecondTargetPointer && mode.getTargets().size() > 1) { + target = mode.getTargets().get(1); + } else { + target = mode.getTargets().get(0); + } + if (target.getNumberOfTargets() == 1) { + String targetName = target.getTargetName(); + sb.append("destroy "); + if (!targetName.startsWith("another")) { + sb.append("target "); + } + sb.append(targetName); + } else { + sb.append("Destroy ").append(CardUtil.numberToText(target.getNumberOfTargets())).append(" target ").append(target.getTargetName()); + } } if (noRegen) { sb.append(". It can't be regenerated"); diff --git a/Mage/src/mage/abilities/effects/common/RemoveFromCombatTargetEffect.java b/Mage/src/mage/abilities/effects/common/RemoveFromCombatTargetEffect.java index 24eba041040..8c39c947169 100644 --- a/Mage/src/mage/abilities/effects/common/RemoveFromCombatTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/RemoveFromCombatTargetEffect.java @@ -1,37 +1,37 @@ /* -* Copyright 2012 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 -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* 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. -*/ - + * Copyright 2012 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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.effects.common; -import mage.constants.Outcome; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -51,11 +51,13 @@ public class RemoveFromCombatTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); - if (permanent != null) { - permanent.removeFromCombat(game); + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + permanent.removeFromCombat(game); + } } - return false; + return true; } @Override @@ -65,6 +67,9 @@ public class RemoveFromCombatTargetEffect extends OneShotEffect { @Override public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } return "Remove target " + mode.getTargets().get(0).getTargetName() + " from combat"; } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToHandTargetEffect.java index 0edac1ef0f5..ebf5260bbb5 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToHandTargetEffect.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,26 +20,24 @@ * 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.effects.common; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; -import static mage.constants.Zone.BATTLEFIELD; -import static mage.constants.Zone.EXILED; -import static mage.constants.Zone.GRAVEYARD; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.util.CardUtil; @@ -72,40 +70,20 @@ public class ReturnToHandTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean result = true; // in case no target is selected Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; } + Cards cardsToHand = new CardsImpl(); + Zone fromZone = game.getState().getZone(targetPointer.getFirst(game, source)); + for (UUID targetId : targetPointer.getTargets(game, source)) { - switch (game.getState().getZone(targetId)) { - case BATTLEFIELD: - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - controller.moveCardToHandWithInfo((Card) permanent, source.getSourceId(), game, Zone.BATTLEFIELD, withName); - } else { - result = false; - } - break; - case GRAVEYARD: - Card card = game.getCard(targetId); - if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, withName); - } else { - result = false; - } - break; - case EXILED: - card = game.getCard(targetId); - if (card != null) { - controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED, withName); - } else { - result = false; - } - break; + MageObject mageObject = game.getObject(targetId); + if (mageObject instanceof Card) { + cardsToHand.add((Card) mageObject); } } - return result; + return controller.moveCards(cardsToHand, fromZone, Zone.HAND, source, game); } @Override diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index d242c5a49de..60ea5a123af 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -612,10 +612,16 @@ public interface Player extends MageItem, Copyable { */ boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game); - boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game); + boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game); + boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); + + boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game); + + boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName); + /** * Uses card.moveToZone and posts a inform message about moving the card * into the game log diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 0bc26e40f1f..032325c8251 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -2869,6 +2869,11 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) { + return moveCards(cards, fromZone, toZone, source, game, true); + } + + @Override + public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { ArrayList cardList = new ArrayList<>(); for (UUID cardId : cards) { if (fromZone.equals(Zone.BATTLEFIELD)) { @@ -2883,20 +2888,30 @@ public abstract class PlayerImpl implements Player, Serializable { } } } - return moveCards(cardList, fromZone, toZone, source, game); + return moveCards(cardList, fromZone, toZone, source, game, withName); } @Override public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game) { + return moveCards(card, fromZone, toZone, source, game, true); + } + + @Override + public boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { ArrayList cardList = new ArrayList<>(); if (card != null) { cardList.add(card); } - return moveCards(cardList, fromZone, toZone, source, game); + return moveCards(cardList, fromZone, toZone, source, game, withName); } @Override public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game) { + return moveCards(cards, fromZone, toZone, source, game, true); + } + + @Override + public boolean moveCards(List cards, Zone fromZone, Zone toZone, Ability source, Game game, boolean withName) { if (cards.isEmpty()) { return true; } @@ -2905,7 +2920,7 @@ public abstract class PlayerImpl implements Player, Serializable { case EXILED: boolean result = false; for (Card card : cards) { - result |= moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, true); + result |= moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName); } return result; case GRAVEYARD: @@ -2913,21 +2928,17 @@ public abstract class PlayerImpl implements Player, Serializable { case HAND: result = false; for (Card card : cards) { - result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone); + result |= moveCardToHandWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, withName); } return result; case BATTLEFIELD: result = false; for (Card card : cards) { - result |= putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId()); + result |= putOntoBattlefieldWithInfo(card, game, fromZone, source == null ? null : source.getSourceId(), false, !withName); } return result; case LIBRARY: result = false; - boolean withName = true; - if (fromZone.equals(Zone.HAND) || fromZone.equals(Zone.LIBRARY)) { - withName = false; - } for (Card card : cards) { result |= moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, withName); } diff --git a/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java b/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java index 78195be8c11..c24c04d65e3 100644 --- a/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java +++ b/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.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.watchers.common; import java.util.HashMap; @@ -34,6 +33,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; @@ -42,16 +42,16 @@ import mage.game.events.ZoneChangeEvent; import mage.watchers.Watcher; /** - * Counts amount of cards put into graveyards of players during the current turn. - * Also the UUIDs of cards that went to graveyard from Battlefield this turn. + * Counts amount of cards put into graveyards of players during the current + * turn. Also the UUIDs of cards that went to graveyard from Battlefield this + * turn. * * @author LevelX2 */ public class CardsPutIntoGraveyardWatcher extends Watcher { private final Map amountOfCardsThisTurn = new HashMap<>(); - private final Set cardsPutToGraveyardFromBattlefield = new HashSet<>(); - + private final Set cardsPutToGraveyardFromBattlefield = new HashSet<>(); public CardsPutIntoGraveyardWatcher() { super("CardsPutIntoGraveyardWatcher", WatcherScope.GAME); @@ -81,7 +81,7 @@ public class CardsPutIntoGraveyardWatcher extends Watcher { } amountOfCardsThisTurn.put(playerId, amount); if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) { - cardsPutToGraveyardFromBattlefield.add(event.getTargetId()); + cardsPutToGraveyardFromBattlefield.add(new MageObjectReference(event.getTargetId(), game)); } } } @@ -95,10 +95,8 @@ public class CardsPutIntoGraveyardWatcher extends Watcher { return 0; } - public Set getCardsPutToGraveyardFromBattlefield() { - Set cards = new HashSet<>(); - cards.addAll(cardsPutToGraveyardFromBattlefield); - return cards; + public Set getCardsPutToGraveyardFromBattlefield() { + return cardsPutToGraveyardFromBattlefield; } @Override