diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java new file mode 100644 index 0000000000..26e5b2b3e2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java @@ -0,0 +1,215 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; +import mage.filter.common.FilterInstantOrSorceryCard; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class LivingLore extends CardImpl { + + public LivingLore(UUID ownerId) { + super(ownerId, 61, "Living Lore", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Avatar"); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // As Living Lore enters the battlefield, exile an instant or sorcery card from your graveyard. + this.addAbility(new EntersBattlefieldAbility(new LivingLoreExileEffect(), "exile an instant or sorcery card from your graveyard")); + + // Living Lore's power and toughness are each equal to the exiled card's converted mana cost. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LivingLoreSetPowerToughnessSourceEffect())); + + // Whenever Living Lore deals combat damage, you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost. + this.addAbility(new DealsCombatDamageTriggeredAbility(new LivingLoreSacrificeEffect(), true)); + } + + public LivingLore(final LivingLore card) { + super(card); + } + + @Override + public LivingLore copy() { + return new LivingLore(this); + } +} + +class LivingLoreExileEffect extends OneShotEffect { + + public LivingLoreExileEffect() { + super(Outcome.Exile); + staticText = "exile an instant or sorcery card from your graveyard"; + } + + public LivingLoreExileEffect(final LivingLoreExileEffect effect) { + super(effect); + } + + @Override + public LivingLoreExileEffect copy() { + return new LivingLoreExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null){ + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard")); + if (controller.chooseTarget(outcome, target, source, game)) { + UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject); + Card card = controller.getGraveyard().get(target.getFirstTarget(), game); + if (card != null) { + controller.moveCardToExileWithInfo(card, exileId, sourceObject.getName(), source.getSourceId(), game, Zone.GRAVEYARD); + } + } + return true; + } + return false; + } + +} + +class LivingLoreSetPowerToughnessSourceEffect extends ContinuousEffectImpl { + + public LivingLoreSetPowerToughnessSourceEffect() { + super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature); + staticText = "{this}'s power and toughness are each equal to the exiled card's converted mana cost"; + } + + public LivingLoreSetPowerToughnessSourceEffect(final LivingLoreSetPowerToughnessSourceEffect effect) { + super(effect); + } + + @Override + public LivingLoreSetPowerToughnessSourceEffect copy() { + return new LivingLoreSetPowerToughnessSourceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject mageObject = source.getSourceObject(game); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && mageObject == null && new MageObjectReference(permanent).refersTo(mageObject)) { + discard(); + return false; + } + UUID exileId = CardUtil.getObjectExileZoneId(game, mageObject); + if (exileId != null) { + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone == null) { + return false; + } + Card exiledCard = null; + for (Card card :exileZone.getCards(game)) { + exiledCard = card; + break; + } + if (exiledCard != null) { + int value = exiledCard.getManaCost().convertedManaCost(); + permanent.getPower().setValue(value); + permanent.getToughness().setValue(value); + } + } + return true; + } +} + +class LivingLoreSacrificeEffect extends OneShotEffect { + + public LivingLoreSacrificeEffect() { + super(Outcome.Benefit); + this.staticText = "you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost"; + } + + public LivingLoreSacrificeEffect(final LivingLoreSacrificeEffect effect) { + super(effect); + } + + @Override + public LivingLoreSacrificeEffect copy() { + return new LivingLoreSacrificeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + MageObject mageObject = source.getSourceObject(game); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && mageObject != null && new MageObjectReference(permanent).refersTo(mageObject)) { + if (permanent.sacrifice(source.getSourceId(), game)) { + UUID exileId = CardUtil.getObjectExileZoneId(game, mageObject); + if (exileId != null) { + ExileZone exileZone = game.getExile().getExileZone(exileId); + Card exiledCard = null; + for (Card card :exileZone.getCards(game)) { + exiledCard = card; + break; + } + if (exiledCard != null) { + if (exiledCard.getSpellAbility().canChooseTarget(game)) { + controller.cast(exiledCard.getSpellAbility(), game, true); + } + } + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MirrorMockery.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MirrorMockery.java new file mode 100644 index 0000000000..424eb9d464 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MirrorMockery.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.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.EmptyToken; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class MirrorMockery extends CardImpl { + + public MirrorMockery(UUID ownerId) { + super(ownerId, 62, "Mirror Mockery", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Copy)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Whenever enchanted creature attacks, you may put a token onto the battlefield that's a copy of that creature. Exile that token at the end of combat. + this.addAbility(new AttacksAttachedTriggeredAbility(new MirrorMockeryEffect(), AttachmentType.AURA, true)); + } + + public MirrorMockery(final MirrorMockery card) { + super(card); + } + + @Override + public MirrorMockery copy() { + return new MirrorMockery(this); + } +} + +class MirrorMockeryEffect extends OneShotEffect { + + public MirrorMockeryEffect() { + super(Outcome.Benefit); + this.staticText = "you may put a token onto the battlefield that's a copy of that creature. Exile that token at the end of combat"; + } + + public MirrorMockeryEffect(final MirrorMockeryEffect effect) { + super(effect); + } + + @Override + public MirrorMockeryEffect copy() { + return new MirrorMockeryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent enchantment = game.getPermanent(source.getSourceId()); + if (enchantment == null || enchantment.getAttachedTo() == null) { + return false; + } + Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); + if (enchanted != null) { + Card card = game.getCard(enchanted.getId()); + if (card != null) { + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); + + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + + ExileTargetEffect exileEffect = new ExileTargetEffect(); + exileEffect.setTargetPointer(new FixedTarget(token.getLastAddedToken())); + DelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game)); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MonasteryLoremaster.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MonasteryLoremaster.java new file mode 100644 index 0000000000..882ee2bb04 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MonasteryLoremaster.java @@ -0,0 +1,84 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class MonasteryLoremaster extends CardImpl { + + private static final FilterCard filter = new FilterCard("target noncreature, nonland card from your graveyard"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + } + + public MonasteryLoremaster(UUID ownerId) { + super(ownerId, 63, "Monastery Loremaster", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Djinn"); + this.subtype.add("Wizard"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Megamorph {5}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}"), true)); + + // When Monastery Loremaster is turned face up, return target noncreature, nonland card from your graveyard to your hand. + Ability ability = new TurnedFaceUpSourceTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + + } + + public MonasteryLoremaster(final MonasteryLoremaster card) { + super(card); + } + + @Override + public MonasteryLoremaster copy() { + return new MonasteryLoremaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java new file mode 100644 index 0000000000..1fcdf2154d --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java @@ -0,0 +1,109 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author LevelX2 + */ +public class MysticMeditation extends CardImpl { + + public MysticMeditation(UUID ownerId) { + super(ownerId, 64, "Mystic Meditation", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{U}"); + this.expansionSetCode = "DTK"; + + // Draw three cards. Then discard two cards unless you discard a creature card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3)); + this.getSpellAbility().addEffect(new MysticMeditationEffect()); + + } + + public MysticMeditation(final MysticMeditation card) { + super(card); + } + + @Override + public MysticMeditation copy() { + return new MysticMeditation(this); + } +} + +class MysticMeditationEffect extends OneShotEffect { + + public MysticMeditationEffect() { + super(Outcome.Damage); + staticText = "Then discard two cards unless you discard a creature card"; + } + + public MysticMeditationEffect(final MysticMeditationEffect effect) { + super(effect); + } + + @Override + public MysticMeditationEffect copy() { + return new MysticMeditationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + FilterCard filter = new FilterCard("creature card to discard"); + filter.add(new CardTypePredicate(CardType.CREATURE)); + if (controller != null + && controller.getHand().count(filter, game) > 0 + && controller.chooseUse(Outcome.Discard, "Do you want to discard a creature card? If you don't, you must discard 2 cards", game)) { + Cost cost = new DiscardTargetCost(new TargetCardInHand(filter)); + if (cost.canPay(source, source.getSourceId(), controller.getId(), game)) { + if (cost.pay(source, game, source.getSourceId(), controller.getId(), false)) { + return true; + } + } + } + if (controller != null) { + controller.discard(2, false, source, game); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiInterceptor.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiInterceptor.java new file mode 100644 index 0000000000..ca20800e08 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiInterceptor.java @@ -0,0 +1,69 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class OjutaiInterceptor extends CardImpl { + + public OjutaiInterceptor(UUID ownerId) { + super(ownerId, 66, "Ojutai Interceptor", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Bird"); + this.subtype.add("Soldier"); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Megamorph {3}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{U}"), true)); + + } + + public OjutaiInterceptor(final OjutaiInterceptor card) { + super(card); + } + + @Override + public OjutaiInterceptor copy() { + return new OjutaiInterceptor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaisBreath.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaisBreath.java new file mode 100644 index 0000000000..a5caf1f878 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaisBreath.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.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.keyword.ReboundAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class OjutaisBreath extends CardImpl { + + public OjutaisBreath(UUID ownerId) { + super(ownerId, 67, "Ojutai's Breath", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{U}"); + this.expansionSetCode = "DTK"; + + // Tap target creature. It doesn't untap during its controller's next untap step. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new TapTargetEffect()); + this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("It")); + + // Rebound + this.addAbility(new ReboundAbility()); + } + + public OjutaisBreath(final OjutaisBreath card) { + super(card); + } + + @Override + public OjutaisBreath copy() { + return new OjutaisBreath(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/PalaceFamiliar.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/PalaceFamiliar.java new file mode 100644 index 0000000000..ab3ceac465 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/PalaceFamiliar.java @@ -0,0 +1,67 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class PalaceFamiliar extends CardImpl { + + public PalaceFamiliar(UUID ownerId) { + super(ownerId, 69, "Palace Familiar", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Bird"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Palace Familiar dies, draw a card. + this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); + } + + public PalaceFamiliar(final PalaceFamiliar card) { + super(card); + } + + @Override + public PalaceFamiliar copy() { + return new PalaceFamiliar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java new file mode 100644 index 0000000000..b3c97cb414 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ProfanerOfTheDead.java @@ -0,0 +1,115 @@ +/* + * 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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ExploitCreatureTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ExploitAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ToughnessPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class ProfanerOfTheDead extends CardImpl { + + public ProfanerOfTheDead(UUID ownerId) { + super(ownerId, 70, "Profaner of the Dead", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Naga"); + this.subtype.add("Wizard"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Exploit + this.addAbility(new ExploitAbility()); + + // When Profaner of the Dead exploits a creature, return to their owners' hands all creatures your opponents control with toughness less than the exploited creature's toughness. + this.addAbility(new ExploitCreatureTriggeredAbility(new ProfanerOfTheDeadReturnEffect(), false, SetTargetPointer.PERMANENT)); + + } + + public ProfanerOfTheDead(final ProfanerOfTheDead card) { + super(card); + } + + @Override + public ProfanerOfTheDead copy() { + return new ProfanerOfTheDead(this); + } +} + +class ProfanerOfTheDeadReturnEffect extends OneShotEffect { + + public ProfanerOfTheDeadReturnEffect() { + super(Outcome.ReturnToHand); + staticText = "return to their owners' hands all creatures your opponents control with toughness less than the exploited creature's toughness"; + } + + public ProfanerOfTheDeadReturnEffect(final ProfanerOfTheDeadReturnEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent exploitedCreature = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (controller != null && exploitedCreature != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(new ToughnessPredicate(Filter.ComparisonType.LessThan, exploitedCreature.getToughness().getValue())); + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + controller.moveCardToHandWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD); + } + return true; + } + return false; + + } + + @Override + public ProfanerOfTheDeadReturnEffect copy() { + return new ProfanerOfTheDeadReturnEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/MimicVat.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/MimicVat.java index 6301e76458..8ef9e3b129 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/MimicVat.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/MimicVat.java @@ -146,7 +146,9 @@ class MimicVatEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) return false; + if (permanent == null) { + return false; + } // return older cards to graveyard for (UUID imprinted : permanent.getImprinted()) { @@ -192,7 +194,9 @@ class MimicVatCreateTokenEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) return false; + if (permanent == null) { + return false; + } if (permanent.getImprinted().size() > 0) { Card card = game.getCard(permanent.getImprinted().get(0)); diff --git a/Mage/src/mage/abilities/common/ExploitCreatureTriggeredAbility.java b/Mage/src/mage/abilities/common/ExploitCreatureTriggeredAbility.java index 953789ca09..23326fb95f 100644 --- a/Mage/src/mage/abilities/common/ExploitCreatureTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/ExploitCreatureTriggeredAbility.java @@ -29,9 +29,11 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.target.targetpointer.FixedTarget; /** * @@ -39,12 +41,20 @@ import mage.game.events.GameEvent; */ public class ExploitCreatureTriggeredAbility extends TriggeredAbilityImpl { + private SetTargetPointer setTargetPointer; + public ExploitCreatureTriggeredAbility(Effect effect, boolean optional) { + this(effect, optional, SetTargetPointer.NONE); + } + + public ExploitCreatureTriggeredAbility(Effect effect, boolean optional, SetTargetPointer setTargetPointer) { super(Zone.ALL, effect, optional); + this.setTargetPointer = setTargetPointer; } public ExploitCreatureTriggeredAbility(final ExploitCreatureTriggeredAbility ability) { super(ability); + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -59,7 +69,15 @@ public class ExploitCreatureTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return event.getSourceId().equals(getSourceId()); + if (event.getSourceId().equals(getSourceId())) { + for (Effect effect: getEffects()) { + if (setTargetPointer.equals(SetTargetPointer.PERMANENT)) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + } + return true; + } + return false; } @Override @@ -67,3 +85,4 @@ public class ExploitCreatureTriggeredAbility extends TriggeredAbilityImpl { return "When {this} exploits a creature, " + super.getRule(); } } + diff --git a/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java b/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java index 2b7a3097cc..a793698f80 100644 --- a/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java @@ -47,6 +47,7 @@ import mage.game.permanent.Permanent; public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousRuleModifyingEffectImpl { private int validForTurnNum; + private String targetName; /** * Attention: This effect won't work with targets controlled by different controllers @@ -57,14 +58,16 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR super(Duration.Custom, Outcome.Detriment, false, true); } - public DontUntapInControllersNextUntapStepTargetEffect(String text) { + public DontUntapInControllersNextUntapStepTargetEffect(String targetName) { this(); - this.staticText = text; + this.targetName = targetName; } public DontUntapInControllersNextUntapStepTargetEffect(final DontUntapInControllersNextUntapStepTargetEffect effect) { super(effect); this.validForTurnNum = effect.validForTurnNum; + this.targetName = effect.targetName; + } @Override @@ -139,12 +142,15 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR @Override public String getText(Mode mode) { - if (staticText.length() > 0) { - return staticText + " doesn't untap during its controller's next untap step"; - } - else { - return "Target " + mode.getTargets().get(0).getTargetName() + " doesn't untap during its controller's next untap step"; - } + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + if (targetName.length() > 0) { + return targetName + " doesn't untap during its controller's next untap step"; + } + else { + return "Target " + mode.getTargets().get(0).getTargetName() + " doesn't untap during its controller's next untap step"; + } } } diff --git a/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java index 24be3c8ab0..fda55a0478 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java @@ -80,7 +80,7 @@ public class ReturnFromGraveyardToHandTargetEffect extends OneShotEffect { } StringBuilder sb = new StringBuilder(); Target target = mode.getTargets().get(0); - sb.append("Return "); + sb.append("return "); if (target.getMaxNumberOfTargets() > 1) { if (target.getMaxNumberOfTargets() != target.getNumberOfTargets()) { sb.append("up to ");