diff --git a/Mage.Sets/src/mage/sets/coldsnap/DarienKingOfKjeldor.java b/Mage.Sets/src/mage/sets/coldsnap/DarienKingOfKjeldor.java new file mode 100644 index 00000000000..cfe809dd842 --- /dev/null +++ b/Mage.Sets/src/mage/sets/coldsnap/DarienKingOfKjeldor.java @@ -0,0 +1,130 @@ +/* + * 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.coldsnap; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.SoldierToken; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class DarienKingOfKjeldor extends CardImpl { + + public DarienKingOfKjeldor(UUID ownerId) { + super(ownerId, 4, "Darien, King of Kjeldor", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); + this.expansionSetCode = "CSP"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Soldier"); + + this.color.setWhite(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever you're dealt damage, you may put that many 1/1 white Soldier creature tokens onto the battlefield. + this.addAbility(new DarienKingOfKjeldorTriggeredAbility()); + } + + public DarienKingOfKjeldor(final DarienKingOfKjeldor card) { + super(card); + } + + @Override + public DarienKingOfKjeldor copy() { + return new DarienKingOfKjeldor(this); + } +} +class DarienKingOfKjeldorTriggeredAbility extends TriggeredAbilityImpl { + + public DarienKingOfKjeldorTriggeredAbility() { + super(Zone.BATTLEFIELD, new DarienKingOfKjeldorEffect(), true); + } + + public DarienKingOfKjeldorTriggeredAbility(final DarienKingOfKjeldorTriggeredAbility ability) { + super(ability); + } + + @Override + public DarienKingOfKjeldorTriggeredAbility copy() { + return new DarienKingOfKjeldorTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if ((event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getTargetId().equals(this.getControllerId()))) { + this.getEffects().get(0).setValue("damageAmount", event.getAmount()); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you are dealt damage, you may put that many 1/1 white Soldier creature tokens onto the battlefield."; + } +} + +class DarienKingOfKjeldorEffect extends OneShotEffect { + + public DarienKingOfKjeldorEffect() { + super(Outcome.Benefit); + } + + public DarienKingOfKjeldorEffect(final DarienKingOfKjeldorEffect effect) { + super(effect); + } + + @Override + public DarienKingOfKjeldorEffect copy() { + return new DarienKingOfKjeldorEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int damage = (Integer) this.getValue("damageAmount"); + return new CreateTokenEffect(new SoldierToken(), damage).apply(game, source); + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/commander2013/HuaTuoHonoredPhysician.java b/Mage.Sets/src/mage/sets/commander2013/HuaTuoHonoredPhysician.java index 3e7001ae7e6..c5fbba6d6f9 100644 --- a/Mage.Sets/src/mage/sets/commander2013/HuaTuoHonoredPhysician.java +++ b/Mage.Sets/src/mage/sets/commander2013/HuaTuoHonoredPhysician.java @@ -31,17 +31,14 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.MyTurnBeforeAttackersDeclaredCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.PutOnLibraryTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.TurnPhase; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.game.turn.Phase; import mage.target.common.TargetCardInYourGraveyard; /** @@ -75,30 +72,3 @@ public class HuaTuoHonoredPhysician extends CardImpl { return new HuaTuoHonoredPhysician(this); } } - -class MyTurnBeforeAttackersDeclaredCondition implements Condition { - private static MyTurnBeforeAttackersDeclaredCondition fInstance = new MyTurnBeforeAttackersDeclaredCondition(); - - public static Condition getInstance() { - return fInstance; - } - - @Override - public boolean apply(Game game, Ability source) { - if (game.getActivePlayerId().equals(source.getControllerId())) { - TurnPhase turnPhase = game.getTurn().getPhase().getType(); - if (turnPhase.equals(TurnPhase.BEGINNING) || turnPhase.equals(TurnPhase.PRECOMBAT_MAIN)) { - return true; - } - if (turnPhase.equals(TurnPhase.COMBAT)) { - return !game.getTurn().isDeclareAttackersStepStarted(); - } - } - return false; - } - - @Override - public String toString() { - return "during your turn, before attackers are declared"; - } -} diff --git a/Mage.Sets/src/mage/sets/gatecrash/VizkopaConfessor.java b/Mage.Sets/src/mage/sets/gatecrash/VizkopaConfessor.java index 57a35a9b8d7..3918afa25ee 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/VizkopaConfessor.java +++ b/Mage.Sets/src/mage/sets/gatecrash/VizkopaConfessor.java @@ -133,12 +133,11 @@ class VizkopaConfessorEffect extends OneShotEffect { targetInHand.setRequired(true); if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Vizkopa Confessor", revealedCards, game); + targetPlayer.revealCards(sourceCard.getName(), revealedCards, game); controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game); Card card = revealedCards.get(targetInHand.getFirstTarget(), game); if (card != null) { - card.moveToExile(null, null, source.getSourceId(), game); - game.informPlayers(new StringBuilder(sourceCard.getName()).append(": Exiled card ").append(card.getName()).toString()); + controller.moveCardToExileWithInfo(card, null, null, source.getSourceId(), game, Zone.HAND); } } return true; diff --git a/Mage.Sets/src/mage/sets/invasion/CaptainSisay.java b/Mage.Sets/src/mage/sets/invasion/CaptainSisay.java new file mode 100644 index 00000000000..06b307a7c46 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/CaptainSisay.java @@ -0,0 +1,79 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LevelX2 + */ +public class CaptainSisay extends CardImpl { + + private static final FilterCard filter = new FilterCard("legendary card"); + + static { + filter.add(new SupertypePredicate("Legendary")); + } + + public CaptainSisay(UUID ownerId) { + super(ownerId, 237, "Captain Sisay", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}{W}"); + this.expansionSetCode = "INV"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Soldier"); + + this.color.setGreen(true); + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {tap}: Search your library for a legendary card, reveal that card, and put it into your hand. Then shuffle your library. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true), new TapSourceCost())); + } + + public CaptainSisay(final CaptainSisay card) { + super(card); + } + + @Override + public CaptainSisay copy() { + return new CaptainSisay(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/HowltoothHollow.java b/Mage.Sets/src/mage/sets/lorwyn/HowltoothHollow.java new file mode 100644 index 00000000000..47c10724fd4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/HowltoothHollow.java @@ -0,0 +1,78 @@ +/* + * 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.lorwyn; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.CardsInHandCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.HideawayPlayEffect; +import mage.abilities.keyword.HideawayAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class HowltoothHollow extends CardImpl { + + public HowltoothHollow(UUID ownerId) { + super(ownerId, 269, "Howltooth Hollow", Rarity.RARE, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "LRW"; + + // Hideaway + this.addAbility(new HideawayAbility(this)); + // {tap}: Add {B} to your mana pool. + this.addAbility(new BlackManaAbility()); + + // {B}, {tap}: You may play the exiled card without paying its mana cost if each player has no cards in hand. + Ability ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, + new HideawayPlayEffect(), + new ManaCostsImpl("{B}"), + new CardsInHandCondition(CardsInHandCondition.CountType.EQUAL_TO, 0, null, TargetController.ANY)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public HowltoothHollow(final HowltoothHollow card) { + super(card); + } + + @Override + public HowltoothHollow copy() { + return new HowltoothHollow(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ninthedition/Blackmail.java b/Mage.Sets/src/mage/sets/ninthedition/Blackmail.java new file mode 100644 index 00000000000..377cb8a3054 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ninthedition/Blackmail.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.ninthedition; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class Blackmail extends mage.sets.onslaught.Blackmail { + + public Blackmail(UUID ownerId) { + super(ownerId); + this.cardNumber = 115; + this.expansionSetCode = "9ED"; + } + + public Blackmail(final Blackmail card) { + super(card); + } + + @Override + public Blackmail copy() { + return new Blackmail(this); + } +} diff --git a/Mage.Sets/src/mage/sets/onslaught/Blackmail.java b/Mage.Sets/src/mage/sets/onslaught/Blackmail.java new file mode 100644 index 00000000000..9fc2a3f2e3c --- /dev/null +++ b/Mage.Sets/src/mage/sets/onslaught/Blackmail.java @@ -0,0 +1,63 @@ +/* + * 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.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.target.TargetPlayer; + +/** + * + * @author LevelX2 + */ +public class Blackmail extends CardImpl { + + public Blackmail(UUID ownerId) { + super(ownerId, 127, "Blackmail", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{B}"); + this.expansionSetCode = "ONS"; + + this.color.setBlack(true); + + // Target player reveals three cards from his or her hand and you choose one of them. That player discards that card. + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(TargetController.ANY, 3)); + this.getSpellAbility().addTarget(new TargetPlayer(true)); + } + + public Blackmail(final Blackmail card) { + super(card); + } + + @Override + public Blackmail copy() { + return new Blackmail(this); + } +} diff --git a/Mage.Sets/src/mage/sets/portalthreekingdoms/CaoCaoLordOfWei.java b/Mage.Sets/src/mage/sets/portalthreekingdoms/CaoCaoLordOfWei.java new file mode 100644 index 00000000000..1b96d601eb8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/portalthreekingdoms/CaoCaoLordOfWei.java @@ -0,0 +1,74 @@ +/* + * 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.portalthreekingdoms; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.MyTurnBeforeAttackersDeclaredCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class CaoCaoLordOfWei extends CardImpl { + + public CaoCaoLordOfWei(UUID ownerId) { + super(ownerId, 68, "Cao Cao, Lord of Wei", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "PTK"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Soldier"); + + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {tap}: Target opponent discards two cards. Activate this ability only during your turn, before attackers are declared. + Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(2), new TapSourceCost(), MyTurnBeforeAttackersDeclaredCondition.getInstance()); + ability.addTarget(new TargetOpponent(true)); + this.addAbility(ability); + } + + public CaoCaoLordOfWei(final CaoCaoLordOfWei card) { + super(card); + } + + @Override + public CaoCaoLordOfWei copy() { + return new CaoCaoLordOfWei(this); + } +} diff --git a/Mage.Sets/src/mage/sets/portalthreekingdoms/DiaochanArtfulBeauty.java b/Mage.Sets/src/mage/sets/portalthreekingdoms/DiaochanArtfulBeauty.java new file mode 100644 index 00000000000..581980e9643 --- /dev/null +++ b/Mage.Sets/src/mage/sets/portalthreekingdoms/DiaochanArtfulBeauty.java @@ -0,0 +1,174 @@ +/* + * 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.portalthreekingdoms; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.MyTurnBeforeAttackersDeclaredCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class DiaochanArtfulBeauty extends CardImpl { + + public DiaochanArtfulBeauty(UUID ownerId) { + super(ownerId, 108, "Diaochan, Artful Beauty", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.expansionSetCode = "PTK"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Advisor"); + + this.color.setRed(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {tap}: Destroy target creature of your choice, then destroy target creature of an opponent's choice. Activate this ability only during your turn, before attackers are declared. + Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new DiaochanArtfulBeautyDestroyEffect(), new TapSourceCost(), MyTurnBeforeAttackersDeclaredCondition.getInstance()); + ability.addTarget(new TargetCreaturePermanent(true)); + ability.addTarget(new TargetOpponentsChoiceCreaturePermanent()); + this.addAbility(ability); + } + + public DiaochanArtfulBeauty(final DiaochanArtfulBeauty card) { + super(card); + } + + @Override + public DiaochanArtfulBeauty copy() { + return new DiaochanArtfulBeauty(this); + } +} + +class DiaochanArtfulBeautyDestroyEffect extends OneShotEffect { + + public DiaochanArtfulBeautyDestroyEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target creature of your choice, then destroy target creature of an opponent's choice"; + } + + public DiaochanArtfulBeautyDestroyEffect(final DiaochanArtfulBeautyDestroyEffect effect) { + super(effect); + } + + @Override + public DiaochanArtfulBeautyDestroyEffect copy() { + return new DiaochanArtfulBeautyDestroyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent firstTarget = game.getPermanent(source.getFirstTarget()); + if (firstTarget != null) { + firstTarget.destroy(source.getSourceId(), game, false); + + } + Permanent secondTarget = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (secondTarget != null) { + secondTarget.destroy(source.getSourceId(), game, false); + } + return true; + } + return false; + } +} + +class TargetOpponentsChoiceCreaturePermanent extends TargetPermanent { + + private UUID opponentId = null; + + public TargetOpponentsChoiceCreaturePermanent() { + super(1, 1, new FilterCreaturePermanent(), false); + this.setRequired(true); + this.targetName = filter.getMessage(); + } + + public TargetOpponentsChoiceCreaturePermanent(final TargetOpponentsChoiceCreaturePermanent target) { + super(target); + this.opponentId = target.opponentId; + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, UUID sourceId, Game game, boolean flag) { + if (opponentId != null) { + return super.canTarget(opponentId, id, sourceId, game, flag); + } + return false; + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (opponentId != null) { + return super.canTarget(opponentId, id, source, game); + } + return false; + } + + @Override + public boolean chooseTarget(Outcome outcome, UUID playerId, Ability source, Game game) { + return super.chooseTarget(outcome, getOpponentId(playerId, source, game), source, game); + } + + @Override + public TargetOpponentsChoiceCreaturePermanent copy() { + return new TargetOpponentsChoiceCreaturePermanent(this); + } + + private UUID getOpponentId(UUID playerId, Ability source, Game game) { + if (opponentId == null) { + TargetOpponent target = new TargetOpponent(true); + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseTarget(Outcome.Detriment, target, source, game)) { + opponentId = target.getFirstTarget(); + } + } + + } + return opponentId; + } + +} diff --git a/Mage.Sets/src/mage/sets/worldwake/MiresToll.java b/Mage.Sets/src/mage/sets/worldwake/MiresToll.java index c3bd2345441..958d9ac3214 100644 --- a/Mage.Sets/src/mage/sets/worldwake/MiresToll.java +++ b/Mage.Sets/src/mage/sets/worldwake/MiresToll.java @@ -27,32 +27,31 @@ */ package mage.sets.worldwake; -import java.util.List; import java.util.UUID; - -import mage.constants.*; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.cards.CardImpl; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.filter.FilterCard; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; import mage.target.TargetPlayer; -import mage.target.common.TargetCardInHand; /** * * @author jeffwadsworth */ public class MiresToll extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("the number of Swamps you control"); + static { + filter.add(new SubtypePredicate("Swamp")); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + public MiresToll(UUID ownerId) { super(ownerId, 60, "Mire's Toll", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{B}"); this.expansionSetCode = "WWK"; @@ -60,8 +59,8 @@ public class MiresToll extends CardImpl { this.color.setBlack(true); // Target player reveals a number of cards from his or her hand equal to the number of Swamps you control. You choose one of them. That player discards that card. - this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new MiresTollEffect()); + this.getSpellAbility().addTarget(new TargetPlayer(true)); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(TargetController.ANY, new PermanentsOnBattlefieldCount(filter))); } @@ -74,70 +73,3 @@ public class MiresToll extends CardImpl { return new MiresToll(this); } } - -class MiresTollEffect extends OneShotEffect { - - private static final FilterLandPermanent filter = new FilterLandPermanent("Swamps"); - - static { - filter.add(new SubtypePredicate("Swamp")); - filter.add(new ControllerPredicate(TargetController.YOU)); - } - - public MiresTollEffect() { - super(Outcome.Discard); - staticText = "Target player reveals a number of cards from his or her hand equal to the number of Swamps you control. You choose one of them. That player discards that card"; - } - - public MiresTollEffect(final MiresTollEffect effect) { - super(effect); - } - - @Override - public MiresTollEffect copy() { - return new MiresTollEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int swamps = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game); - Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (swamps > 0 && targetPlayer != null) { - Cards revealedCards = new CardsImpl(Zone.PICK); - int amount = Math.min(targetPlayer.getHand().size(), swamps); - FilterCard filter = new FilterCard("card in target player's hand"); - TargetCardInHand chosenCards = new TargetCardInHand(amount, amount, filter); - chosenCards.setRequired(true); - chosenCards.setNotTarget(true); - if (chosenCards.canChoose(targetPlayer.getId(), game) && targetPlayer.choose(Outcome.Discard, targetPlayer.getHand(), chosenCards, game)) { - if (!chosenCards.getTargets().isEmpty()) { - List targets = chosenCards.getTargets(); - for (UUID targetid : targets) { - Card card = game.getCard(targetid); - if (card != null) { - revealedCards.add(card); - } - } - } - } - - targetPlayer.revealCards("Mire's Toll", revealedCards, game); - - Player you = game.getPlayer(source.getControllerId()); - - if (you != null) { - TargetCard yourChoice = new TargetCard(Zone.PICK, new FilterCard()); - yourChoice.setRequired(true); - yourChoice.setNotTarget(true); - if (you.choose(Outcome.Benefit, revealedCards, yourChoice, game)) { - Card card = targetPlayer.getHand().get(yourChoice.getFirstTarget(), game); - if (card != null) { - return targetPlayer.discard(card, source, game); - } - } - } - } - - return false; - } -} diff --git a/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java b/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java index e84518124d2..ea01a1f4f81 100644 --- a/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java +++ b/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java @@ -27,59 +27,150 @@ */ package mage.abilities.condition.common; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.constants.TargetController; import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; /** - * Cards in controller hand condition. This condition can decorate other conditions - * as well as be used standalone. + * Cards in controller hand condition. This condition can decorate other + * conditions as well as be used standalone. * * * @author LevelX */ public class CardsInHandCondition implements Condition { - public static enum CountType { MORE_THAN, FEWER_THAN, EQUAL_TO }; + public static enum CountType { + MORE_THAN, FEWER_THAN, EQUAL_TO + }; + private Condition condition; private CountType type; private int count; + private TargetController targetController; - public CardsInHandCondition() { - this(CountType.EQUAL_TO, 0); - } - - public CardsInHandCondition (CountType type, int count ) { - this.type = type; - this.count = count; + public CardsInHandCondition() { + this(CountType.EQUAL_TO, 0); } - public CardsInHandCondition (CountType type, int count, Condition conditionToDecorate ) { - this(type, count); + public CardsInHandCondition(CountType type, int count) { + this(type, count, null); + } + + public CardsInHandCondition(CountType type, int count, Condition conditionToDecorate) { + this(type, count, conditionToDecorate, TargetController.YOU); + } + + public CardsInHandCondition(CountType type, int count, Condition conditionToDecorate, TargetController targetController) { + this.type = type; + this.count = count; this.condition = conditionToDecorate; + this.targetController = targetController; } @Override - public boolean apply(Game game, Ability source) { + public boolean apply(Game game, Ability source) { boolean conditionApplies = false; + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + switch (targetController) { + case YOU: + switch (this.type) { + case FEWER_THAN: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() < this.count; + break; + case MORE_THAN: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() > this.count; + break; + case EQUAL_TO: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() == this.count; + break; + } + break; + case ANY: + boolean conflict = false; + switch (this.type) { + case FEWER_THAN: + for (UUID playerId :controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.getHand().size() >= this.count) { + conflict = true; + break; + } + } + } + break; + case MORE_THAN: + for (UUID playerId :controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.getHand().size() <= this.count) { + conflict = true; + break; + } + } + } + break; + case EQUAL_TO: + for (UUID playerId :controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.getHand().size() != this.count) { + conflict = true; + break; + } + } + } + break; + } + conditionApplies = !conflict; + break; + default: + throw new UnsupportedOperationException("Value of TargetController not supported for this class."); + } - switch ( this.type ) { - case FEWER_THAN: - conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() < this.count; - break; - case MORE_THAN: - conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() > this.count; - break; - case EQUAL_TO: - conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() == this.count; - break; - } - - //If a decorated condition exists, check it as well and apply them together. - if ( this.condition != null ) { - conditionApplies = conditionApplies && this.condition.apply(game, source); + //If a decorated condition exists, check it as well and apply them together. + if (this.condition != null) { + conditionApplies = conditionApplies && this.condition.apply(game, source); + } } return conditionApplies; } + + @Override + public String toString() { + int workCount = count; + StringBuilder sb = new StringBuilder("if "); + switch (targetController) { + case YOU: + sb.append(" you have"); + break; + case ANY: + sb.append(" each player has"); + break; + } + switch (this.type) { + case FEWER_THAN: + sb.append(" less or equal than "); + workCount++; + break; + case MORE_THAN: + sb.append(" more than "); + break; + } + if (count == 0) { + sb.append(" no "); + } else { + sb.append(CardUtil.numberToText(workCount)); + } + sb.append("cards in hand"); + return sb.toString(); + } + } diff --git a/Mage/src/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java b/Mage/src/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java new file mode 100644 index 00000000000..f96e2e71fd3 --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java @@ -0,0 +1,66 @@ +/* + * 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.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.constants.TurnPhase; +import mage.game.Game; + +/** + * + * @author LevelX2 + */ +public class MyTurnBeforeAttackersDeclaredCondition implements Condition { + private static final MyTurnBeforeAttackersDeclaredCondition fInstance = new MyTurnBeforeAttackersDeclaredCondition(); + + public static Condition getInstance() { + return fInstance; + } + + @Override + public boolean apply(Game game, Ability source) { + if (game.getActivePlayerId().equals(source.getControllerId())) { + TurnPhase turnPhase = game.getTurn().getPhase().getType(); + if (turnPhase.equals(TurnPhase.BEGINNING) || turnPhase.equals(TurnPhase.PRECOMBAT_MAIN)) { + return true; + } + if (turnPhase.equals(TurnPhase.COMBAT)) { + return !game.getTurn().isDeclareAttackersStepStarted(); + } + } + return false; + } + + @Override + public String toString() { + return "during your turn, before attackers are declared"; + } +} + diff --git a/Mage/src/mage/abilities/dynamicvalue/common/DevotionCount.java b/Mage/src/mage/abilities/dynamicvalue/common/DevotionCount.java index d9921017872..73b8b10ffd4 100644 --- a/Mage/src/mage/abilities/dynamicvalue/common/DevotionCount.java +++ b/Mage/src/mage/abilities/dynamicvalue/common/DevotionCount.java @@ -20,7 +20,7 @@ import mage.game.permanent.Permanent; */ public class DevotionCount implements DynamicValue { - private ArrayList devotionColors = new ArrayList(); + private ArrayList devotionColors = new ArrayList<>(); public DevotionCount(ColoredManaSymbol... devotionColor) { this.devotionColors.addAll(Arrays.asList(devotionColor)); diff --git a/Mage/src/mage/abilities/dynamicvalue/common/StaticValue.java b/Mage/src/mage/abilities/dynamicvalue/common/StaticValue.java index f92336ea5a1..3a9c3ecf209 100644 --- a/Mage/src/mage/abilities/dynamicvalue/common/StaticValue.java +++ b/Mage/src/mage/abilities/dynamicvalue/common/StaticValue.java @@ -7,13 +7,19 @@ import mage.game.Game; public class StaticValue implements DynamicValue { private int value = 0; - + private String message; + public StaticValue(int value) { + this(value, ""); + } + public StaticValue(int value, String message) { this.value = value; + this.message = message; } public StaticValue(final StaticValue staticValue) { this.value = staticValue.value; + this.message = staticValue.message; } @Override @@ -33,6 +39,6 @@ public class StaticValue implements DynamicValue { @Override public String getMessage() { - return ""; + return message; } } diff --git a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java index 1619e1eef88..4d4ba0a3b3c 100644 --- a/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java @@ -27,9 +27,15 @@ */ package mage.abilities.effects.common.discard; +import java.util.List; +import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; @@ -37,6 +43,8 @@ import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; +import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; /** * @@ -46,6 +54,8 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect 0) { - TargetCard target = new TargetCard(Zone.PICK, filter); - target.setRequired(true); - if (you.choose(Outcome.Benefit, player.getHand(), target, game)) { - Card card = player.getHand().get(target.getFirstTarget(), game); - if (card != null) { - return player.discard(card, source, game); + if (player != null && controller != null) { + if (revealAllCards) { + this.numberCardsToReveal = new StaticValue(player.getHand().size()); + } + int number = this.numberCardsToReveal.calculate(game, source); + if (number > 0) { + Cards revealedCards = new CardsImpl(Zone.HAND); + number = Math.min(player.getHand().size(), number); + if (player.getHand().size() > number) { + TargetCardInHand chosenCards = new TargetCardInHand(number, number, new FilterCard("card in target player's hand")); + chosenCards.setRequired(true); + chosenCards.setNotTarget(true); + if (chosenCards.canChoose(player.getId(), game) && player.choose(Outcome.Discard, player.getHand(), chosenCards, game)) { + if (!chosenCards.getTargets().isEmpty()) { + List targets = chosenCards.getTargets(); + for (UUID targetid : targets) { + Card card = game.getCard(targetid); + if (card != null) { + revealedCards.add(card); + } + } + } + } + } else { + revealedCards.addAll(player.getHand()); + } + + player.revealCards(sourceCard != null ? sourceCard.getName() :"Discard", revealedCards, game); + if (revealedCards.count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { + TargetCard target = new TargetCard(Zone.HAND, filter); + target.setRequired(true); + if (controller.choose(Outcome.Benefit, revealedCards, target, game)) { + Card card = revealedCards.get(target.getFirstTarget(), game); + if (card != null) { + return player.discard(card, source, game); + } } } + } return true; } @@ -111,8 +175,27 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect