diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/MinamosMeddling.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/MinamosMeddling.java new file mode 100644 index 0000000000..64e066f576 --- /dev/null +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/MinamosMeddling.java @@ -0,0 +1,127 @@ +/* + * 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.betrayersofkamigawa; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.OneShotEffect; +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.SpellAbilityType; +import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetSpell; + +/** + * + * @author LevelX2 + */ +public class MinamosMeddling extends CardImpl { + + public MinamosMeddling(UUID ownerId) { + super(ownerId, 42, "Minamo's Meddling", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); + this.expansionSetCode = "BOK"; + + this.color.setBlue(true); + + // Counter target spell. That spell's controller reveals his or her hand, then discards each card with the same name as a card spliced onto that spell. + this.getSpellAbility().addTarget(new TargetSpell(new FilterSpell())); + this.getSpellAbility().addEffect(new MinamosMeddlingCounterTargetEffect()); + } + + public MinamosMeddling(final MinamosMeddling card) { + super(card); + } + + @Override + public MinamosMeddling copy() { + return new MinamosMeddling(this); + } +} + +class MinamosMeddlingCounterTargetEffect extends OneShotEffect { + + public MinamosMeddlingCounterTargetEffect() { + super(Outcome.Benefit); + staticText = "Counter target spell. That spell's controller reveals his or her hand, then discards each card with the same name as a card spliced onto that spell"; + } + + public MinamosMeddlingCounterTargetEffect(final MinamosMeddlingCounterTargetEffect effect) { + super(effect); + } + + @Override + public MinamosMeddlingCounterTargetEffect copy() { + return new MinamosMeddlingCounterTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null) { + for (UUID targetId : getTargetPointer().getTargets(game, source) ) { + Spell spell = game.getStack().getSpell(targetId); + if (spell != null) { + game.getStack().counter(targetId, source.getSourceId(), game); + Player spellController = game.getPlayer(spell.getControllerId()); + if (spellController != null) { + spellController.revealCards(sourceObject.getLogName(), spellController.getHand(), game); + Cards cardsToDiscard = new CardsImpl(); + for (SpellAbility spellAbility : spell.getSpellAbilities()) { + if (spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) { + for (Card card: spellController.getHand().getCards(game)) { + if (card.getName().equals(spellAbility.getCardName()) && !cardsToDiscard.contains(card.getId())) { + cardsToDiscard.add(card); + } + } + } + } + if (!cardsToDiscard.isEmpty()) { + for (Card card :cardsToDiscard.getCards(game)) { + spellController.discard(card, source, game); + } + } + } + + } + } + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/TomorrowAzamisFamiliar.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/TomorrowAzamisFamiliar.java new file mode 100644 index 0000000000..ce477cad41 --- /dev/null +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/TomorrowAzamisFamiliar.java @@ -0,0 +1,110 @@ +/* + * 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.betrayersofkamigawa; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; + +/** + * + * @author LevelX2 + */ +public class TomorrowAzamisFamiliar extends CardImpl { + + public TomorrowAzamisFamiliar(UUID ownerId) { + super(ownerId, 58, "Tomorrow, Azami's Familiar", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{U}"); + this.expansionSetCode = "BOK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setBlue(true); + this.power = new MageInt(1); + this.toughness = new MageInt(5); + + // If you would draw a card, look at the top three cards of your library instead. Put one of those cards into your hand and the rest on the bottom of your library in any order. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TomorrowAzamisFamiliarReplacementEffect())); + } + + public TomorrowAzamisFamiliar(final TomorrowAzamisFamiliar card) { + super(card); + } + + @Override + public TomorrowAzamisFamiliar copy() { + return new TomorrowAzamisFamiliar(this); + } +} + +class TomorrowAzamisFamiliarReplacementEffect extends ReplacementEffectImpl { + + TomorrowAzamisFamiliarReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "If you would draw a card, look at the top three cards of your library instead. Put one of those cards into your hand and the rest on the bottom of your library in any order"; + } + + TomorrowAzamisFamiliarReplacementEffect(final TomorrowAzamisFamiliarReplacementEffect effect) { + super(effect); + } + + @Override + public TomorrowAzamisFamiliarReplacementEffect copy() { + return new TomorrowAzamisFamiliarReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + new LookLibraryAndPickControllerEffect(new StaticValue(3), false, new StaticValue(1), new FilterCard(), Zone.LIBRARY, false, false) + .apply(game, source); + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return EventType.DRAW_CARD.equals(event.getType()) && event.getPlayerId().equals(source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java new file mode 100644 index 0000000000..a0ec672be1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.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.betrayersofkamigawa; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.costs.common.ReturnToHandTargetCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.combat.UnblockableTargetEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.ShroudAbility; +import mage.abilities.keyword.SpliceOntoArcaneAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class VeilOfSecrecy extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a blue creature"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLUE)); + } + + public VeilOfSecrecy(UUID ownerId) { + super(ownerId, 59, "Veil of Secrecy", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "BOK"; + this.subtype.add("Arcane"); + + this.color.setBlue(true); + + // Target creature gains shroud until end of turn and is unblockable this turn. + Effect effect = new GainAbilityTargetEffect(ShroudAbility.getInstance(), Duration.EndOfTurn); + effect.setText("Target creature gains shroud until end of turn"); + this.getSpellAbility().addEffect(effect); + effect = new UnblockableTargetEffect(); + effect.setText("and is unblockable this turn"); + this.getSpellAbility().addEffect(effect); + + // Splice onto Arcane-Return a blue creature you control to its owner's hand. + this.addAbility(new SpliceOntoArcaneAbility(new ReturnToHandTargetCost(new TargetControlledCreaturePermanent(filter)))); + } + + public VeilOfSecrecy(final VeilOfSecrecy card) { + super(card); + } + + @Override + public VeilOfSecrecy copy() { + return new VeilOfSecrecy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/newphyrexia/SurgicalExtraction.java b/Mage.Sets/src/mage/sets/newphyrexia/SurgicalExtraction.java index cfe0ec8513..65dc483e9f 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/SurgicalExtraction.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/SurgicalExtraction.java @@ -105,6 +105,9 @@ class SurgicalExtractionEffect extends OneShotEffect { Card card = game.getCard(source.getFirstTarget()); Player player = game.getPlayer(source.getControllerId()); + // 6/1/2011 "Any number of cards" means just that. If you wish, you can choose to + // leave some or all of the cards with the same name as the targeted card, + // including that card, in the zone they're in. if (card != null && player != null) { Player targetPlayer = game.getPlayer(card.getOwnerId()); if (targetPlayer != null) { diff --git a/Mage/src/mage/abilities/SpellAbility.java b/Mage/src/mage/abilities/SpellAbility.java index eee99fdc21..a6006d52b1 100644 --- a/Mage/src/mage/abilities/SpellAbility.java +++ b/Mage/src/mage/abilities/SpellAbility.java @@ -28,15 +28,19 @@ package mage.abilities; +import java.util.UUID; import mage.MageObject; import mage.abilities.costs.mana.ManaCost; import mage.abilities.keyword.FlashAbility; import mage.cards.SplitCard; -import mage.constants.*; +import mage.constants.AbilityType; +import mage.constants.AsThoughEffectType; +import mage.constants.SpellAbilityType; +import static mage.constants.SpellAbilityType.SPLIT_FUSED; +import mage.constants.TimingRule; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; - -import java.util.UUID; import mage.players.Player; /** @@ -46,6 +50,7 @@ import mage.players.Player; public class SpellAbility extends ActivatedAbilityImpl { protected SpellAbilityType spellAbilityType; + protected String cardName; public SpellAbility(ManaCost cost, String cardName) { this(cost, cardName, Zone.HAND); @@ -57,6 +62,7 @@ public class SpellAbility extends ActivatedAbilityImpl { public SpellAbility(ManaCost cost, String cardName, Zone zone, SpellAbilityType spellAbilityType) { super(AbilityType.SPELL, zone); + this.cardName = cardName; this.spellAbilityType = spellAbilityType; this.addManaCost(cost); switch(spellAbilityType) { @@ -72,6 +78,7 @@ public class SpellAbility extends ActivatedAbilityImpl { public SpellAbility(SpellAbility ability) { super(ability); this.spellAbilityType = ability.spellAbilityType; + this.cardName = ability.cardName; } public boolean spellCanBeActivatedRegularlyNow(UUID playerId, Game game) { @@ -171,4 +178,8 @@ public class SpellAbility extends ActivatedAbilityImpl { this.spellAbilityType = spellAbilityType; } + public String getCardName() { + return cardName; + } + }