diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/HedonistsTrove.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/HedonistsTrove.java new file mode 100644 index 0000000000..b79f31b402 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/HedonistsTrove.java @@ -0,0 +1,205 @@ +/* + * 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.ArrayList; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AsThoughEffectType; +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.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class HedonistsTrove extends CardImpl { + + public HedonistsTrove(UUID ownerId) { + super(ownerId, 106, "Hedonist's Trove", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{B}{B}"); + this.expansionSetCode = "DTK"; + + // When Hedonist's Trove enters the battlefield, exile all cards from target opponent's graveyard. + Ability ability = new EntersBattlefieldTriggeredAbility(new HedonistsTroveExileEffect()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + + // You may play land cards exiled by Hedonist's Trove. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HedonistsTrovePlayLandEffect())); + + // You may cast nonland cards exiled with Hedonist's Trove. You can't cast more than one spell this way each turn. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HedonistsTroveCastNonlandCardsEffect())); + + } + + public HedonistsTrove(final HedonistsTrove card) { + super(card); + } + + @Override + public HedonistsTrove copy() { + return new HedonistsTrove(this); + } +} + +class HedonistsTroveExileEffect extends OneShotEffect { + + public HedonistsTroveExileEffect() { + super(Outcome.Exile); + staticText = "exile all cards from target opponent's graveyard"; + } + + @Override + public HedonistsTroveExileEffect copy() { + return new HedonistsTroveExileEffect(); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && targetPlayer != null && sourceObject != null) { + UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject); + ArrayList graveyard = new ArrayList<>(targetPlayer.getGraveyard()); + for (UUID cardId : graveyard) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, exileId, sourceObject.getName(), source.getSourceId(), game, Zone.GRAVEYARD); + } + } + return true; + } + return false; + } +} + +class HedonistsTrovePlayLandEffect extends AsThoughEffectImpl { + + public HedonistsTrovePlayLandEffect() { + super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "You may play land cards exiled by {this}"; + } + + public HedonistsTrovePlayLandEffect(final HedonistsTrovePlayLandEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HedonistsTrovePlayLandEffect copy() { + return new HedonistsTrovePlayLandEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(objectId); + MageObject sourceObject = source.getSourceObject(game); + if (card != null && card.getCardType().contains(CardType.LAND) && sourceObject != null) { + UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject); + if (exileId != null) { + ExileZone exileZone = game.getState().getExile().getExileZone(exileId); + return exileZone != null && exileZone.contains(objectId); + } + } + return false; + } +} + +class HedonistsTroveCastNonlandCardsEffect extends AsThoughEffectImpl { + + private int turnNumber; + private UUID cardId; + + public HedonistsTroveCastNonlandCardsEffect() { + super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "You may cast nonland cards exiled with {this}. You can't cast more than one spell this way each turn"; + } + + public HedonistsTroveCastNonlandCardsEffect(final HedonistsTroveCastNonlandCardsEffect effect) { + super(effect); + this.turnNumber = effect.turnNumber; + this.cardId = effect.cardId; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HedonistsTroveCastNonlandCardsEffect copy() { + return new HedonistsTroveCastNonlandCardsEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(objectId); + MageObject sourceObject = source.getSourceObject(game); + if (card != null && !card.getCardType().contains(CardType.LAND) && sourceObject != null) { + UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject); + if (exileId != null) { + ExileZone exileZone = game.getState().getExile().getExileZone(exileId); + if (exileZone != null && exileZone.contains(objectId)) { + if (game.getTurnNum() == turnNumber) { + if (!exileZone.contains(cardId)) { + // last checked card this turn is no longer exiled, so you can't cast another with this effect + // TODO: Handle if card was cast/removed from exile with effect from another card. + // If so, this effect could prevent player from casting although he should be able to use it + return false; + } + } + this.turnNumber = game.getTurnNum(); + this.cardId = objectId; + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MarshHulk.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MarshHulk.java new file mode 100644 index 0000000000..f2e8fb675e --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MarshHulk.java @@ -0,0 +1,64 @@ +/* + * 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.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class MarshHulk extends CardImpl { + + public MarshHulk(UUID ownerId) { + super(ownerId, 109, "Marsh Hulk", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Zombie"); + this.subtype.add("Ogre"); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Megamorph {6}{B} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{6}{B}"), true)); + } + + public MarshHulk(final MarshHulk card) { + super(card); + } + + @Override + public MarshHulk copy() { + return new MarshHulk(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MinisterOfPain.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MinisterOfPain.java new file mode 100644 index 0000000000..2bb6ac99a6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MinisterOfPain.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.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.ExploitCreatureTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.keyword.ExploitAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class MinisterOfPain extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public MinisterOfPain(UUID ownerId) { + super(ownerId, 111, "Minister of Pain", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Exploit + this.addAbility(new ExploitAbility()); + + // When Minister of Pain explots a creature, creatures your opponents control get -1/-1 until end of turn. + this.addAbility(new ExploitCreatureTriggeredAbility(new BoostAllEffect(-1,-1, Duration.EndOfTurn, filter, false), false)); + + } + + public MinisterOfPain(final MinisterOfPain card) { + super(card); + } + + @Override + public MinisterOfPain copy() { + return new MinisterOfPain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/QarsiSadist.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/QarsiSadist.java new file mode 100644 index 0000000000..abeee78065 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/QarsiSadist.java @@ -0,0 +1,76 @@ +/* + * 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.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.keyword.ExploitAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class QarsiSadist extends CardImpl { + + public QarsiSadist(UUID ownerId) { + super(ownerId, 113, "Qarsi Sadist", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Exploit + this.addAbility(new ExploitAbility()); + // When Qarsi Sadist exploits a creature, target opponent loses 2 life and you gain 2 life. + Ability ability = new ExploitCreatureTriggeredAbility(new LoseLifeTargetEffect(2), false); + ability.addTarget(new TargetOpponent()); + Effect effect = new GainLifeEffect(2); + effect.setText("and you gain 2 life"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public QarsiSadist(final QarsiSadist card) { + super(card); + } + + @Override + public QarsiSadist copy() { + return new QarsiSadist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/RakshasaGravecaller.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/RakshasaGravecaller.java new file mode 100644 index 0000000000..f30c57e476 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/RakshasaGravecaller.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.common.ExploitCreatureTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.ExploitAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.game.permanent.token.ZombieToken; + +/** + * + * @author LevelX2 + */ +public class RakshasaGravecaller extends CardImpl { + + public RakshasaGravecaller(UUID ownerId) { + super(ownerId, 114, "Rakshasa Gravecaller", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Cat"); + this.subtype.add("Demon"); + this.power = new MageInt(3); + this.toughness = new MageInt(6); + + // Exploit + this.addAbility(new ExploitAbility()); + + // When Rakshasa Gravecaller exploits a creature, put two 2/2 black Zombie creature tokens onto the battlefield. + this.addAbility(new ExploitCreatureTriggeredAbility(new CreateTokenEffect(new ZombieToken("DTK"), 2), false)); + } + + public RakshasaGravecaller(final RakshasaGravecaller card) { + super(card); + } + + @Override + public RakshasaGravecaller copy() { + return new RakshasaGravecaller(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/RecklessImp.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/RecklessImp.java new file mode 100644 index 0000000000..0cc522cb2d --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/RecklessImp.java @@ -0,0 +1,70 @@ +/* + * 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.CantBlockAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.DashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class RecklessImp extends CardImpl { + + public RecklessImp(UUID ownerId) { + super(ownerId, 115, "Reckless Imp", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Imp"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Reckless Imp can't block. + this.addAbility(new CantBlockAbility()); + + // Dash {1}{B} + this.addAbility(new DashAbility(this, "{1}{B}")); + } + + public RecklessImp(final RecklessImp card) { + super(card); + } + + @Override + public RecklessImp copy() { + return new RecklessImp(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/RisenExecutioner.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/RisenExecutioner.java new file mode 100644 index 0000000000..a1b4f29bab --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/RisenExecutioner.java @@ -0,0 +1,175 @@ +/* + * 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.CantBlockAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherCardPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class RisenExecutioner extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie creatures"); + + static { + filter.add(new SubtypePredicate("Zombie")); + } + + public RisenExecutioner(UUID ownerId) { + super(ownerId, 116, "Risen Executioner", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Zombie"); + this.subtype.add("Warrior"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Risen Executioner can't block. + this.addAbility(new CantBlockAbility()); + + // Other Zombie creatures you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + + // You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard. + // TODO: cost increase does not happen if Risen Executioner is cast grom graveyard because of other effects + Ability ability = new SimpleStaticAbility(Zone.ALL, new RisenExecutionerCastEffect()); + ability.addEffect(new RisenExecutionerCostIncreasingEffect()); + this.addAbility(ability); + + } + + public RisenExecutioner(final RisenExecutioner card) { + super(card); + } + + @Override + public RisenExecutioner copy() { + return new RisenExecutioner(this); + } +} + +class RisenExecutionerCastEffect extends AsThoughEffectImpl { + + RisenExecutionerCastEffect() { + super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit); + staticText = "You may cast {this} from your graveyard"; + } + + RisenExecutionerCastEffect(final RisenExecutionerCastEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public RisenExecutionerCastEffect copy() { + return new RisenExecutionerCastEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + if (sourceId.equals(source.getSourceId())) { + Card card = game.getCard(source.getSourceId()); + if (card != null + && card.getOwnerId().equals(affectedControllerId) + && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { + return true; + } + } + return false; + } +} + +class RisenExecutionerCostIncreasingEffect extends CostModificationEffectImpl { + + protected static final FilterCreatureCard filter = new FilterCreatureCard(); + + static { + filter.add(new AnotherCardPredicate()); + } + + RisenExecutionerCostIncreasingEffect () { + super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = "if you pay {1} more to cast it for each other creature card in your graveyard"; + } + + RisenExecutionerCostIncreasingEffect(final RisenExecutionerCostIncreasingEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + CardUtil.increaseCost(abilityToModify, controller.getGraveyard().count(filter, source.getSourceId(), source.getControllerId(), game)); + } + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getSourceId().equals(source.getSourceId())) { + Spell spell = game.getStack().getSpell(abilityToModify.getSourceId()); + return spell != null && spell.getFromZone() == Zone.GRAVEYARD; + } + return false; + } + + @Override + public RisenExecutionerCostIncreasingEffect copy() { + return new RisenExecutionerCostIncreasingEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SelfInflictedWound.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SelfInflictedWound.java new file mode 100644 index 0000000000..8854fb26c7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SelfInflictedWound.java @@ -0,0 +1,117 @@ +/* + * 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.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class SelfInflictedWound extends CardImpl { + + public SelfInflictedWound(UUID ownerId) { + super(ownerId, 117, "Self-Inflicted Wound", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); + this.expansionSetCode = "DTK"; + + // Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life. + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new SelfInflictedWoundEffect()); + + } + + public SelfInflictedWound(final SelfInflictedWound card) { + super(card); + } + + @Override + public SelfInflictedWound copy() { + return new SelfInflictedWound(this); + } +} + +class SelfInflictedWoundEffect extends OneShotEffect { + + SelfInflictedWoundEffect() { + super(Outcome.Sacrifice); + staticText = "Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life"; + } + + SelfInflictedWoundEffect(SelfInflictedWoundEffect effect) { + super(effect); + } + + @Override + public SelfInflictedWoundEffect copy() { + return new SelfInflictedWoundEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetOpponent = game.getPlayer(source.getTargets().getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (targetOpponent == null || controller == null) { + return false; + } + FilterControlledPermanent filter = new FilterControlledPermanent("a green or white creature"); + filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(Predicates.or(new ColorPredicate(ObjectColor.GREEN), new ColorPredicate(ObjectColor.WHITE))); + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); + + if (target.canChoose(targetOpponent.getId(), game)) { + targetOpponent.chooseTarget(Outcome.Sacrifice, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + if (permanent.sacrifice(source.getSourceId(), game)) { + controller.loseLife(2, game); + } + } + + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ServantOfTheScale.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ServantOfTheScale.java index 426e84d95c..0aeef1a3d8 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/ServantOfTheScale.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ServantOfTheScale.java @@ -62,7 +62,7 @@ public class ServantOfTheScale extends CardImpl { this.toughness = new MageInt(0); // Servant of the Scale enters the battlefield with a +1/+1 counter on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), "with a +1/+1 counters on it")); // When Servant of the Scale dies, put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counter on Servant of the Scale. diff --git a/Mage.Sets/src/mage/sets/innistrad/TributeToHunger.java b/Mage.Sets/src/mage/sets/innistrad/TributeToHunger.java index cab144ae68..e7bd142dee 100644 --- a/Mage.Sets/src/mage/sets/innistrad/TributeToHunger.java +++ b/Mage.Sets/src/mage/sets/innistrad/TributeToHunger.java @@ -54,8 +54,6 @@ public class TributeToHunger extends CardImpl { super(ownerId, 119, "Tribute to Hunger", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{B}"); this.expansionSetCode = "ISD"; - this.color.setBlack(true); - // Target opponent sacrifices a creature. You gain life equal to that creature's toughness. this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addEffect(new TributeToHungerEffect()); @@ -98,12 +96,11 @@ class TributeToHungerEffect extends OneShotEffect { TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); if (target.canChoose(player.getId(), game)) { - player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); - + player.chooseTarget(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { - controller.gainLife(permanent.getToughness().getValue(), game); - return permanent.sacrifice(source.getSourceId(), game); + permanent.sacrifice(source.getSourceId(), game); + controller.gainLife(permanent.getToughness().getValue(), game); } return true; } diff --git a/Mage.Sets/src/mage/sets/magic2012/CemeteryReaper.java b/Mage.Sets/src/mage/sets/magic2012/CemeteryReaper.java index f10578a13f..91a639adbb 100644 --- a/Mage.Sets/src/mage/sets/magic2012/CemeteryReaper.java +++ b/Mage.Sets/src/mage/sets/magic2012/CemeteryReaper.java @@ -55,6 +55,7 @@ import mage.target.common.TargetCardInGraveyard; public class CemeteryReaper extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie creatures"); + static { filter.add(new SubtypePredicate("Zombie")); } @@ -63,10 +64,13 @@ public class CemeteryReaper extends CardImpl { super(ownerId, 86, "Cemetery Reaper", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); this.expansionSetCode = "M12"; this.subtype.add("Zombie"); - this.color.setBlack(true); this.power = new MageInt(2); this.toughness = new MageInt(2); + + // Other Zombie creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + + // {2}{B}, {T} : Exile target creature card from a graveyard. Put a 2/2 black Zombie creature token onto the battlefield. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new ManaCostsImpl("{2}{B}")); ability.addCost(new TapSourceCost()); ability.addEffect(new CreateTokenEffect(new ZombieToken("M12"))); diff --git a/Mage/src/mage/abilities/effects/common/LoseLifeSourceControllerEffect.java b/Mage/src/mage/abilities/effects/common/LoseLifeSourceControllerEffect.java index fe5df7b4d2..f9239424cd 100644 --- a/Mage/src/mage/abilities/effects/common/LoseLifeSourceControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LoseLifeSourceControllerEffect.java @@ -76,7 +76,7 @@ public class LoseLifeSourceControllerEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("You lose ").append(amount.toString()).append(" life"); + sb.append("you lose ").append(amount.toString()).append(" life"); String message = amount.getMessage(); if (message.length() > 0) { sb.append(" for each "); diff --git a/Mage/src/mage/abilities/effects/common/LoseLifeTargetEffect.java b/Mage/src/mage/abilities/effects/common/LoseLifeTargetEffect.java index 89006e4ded..b057048f2d 100644 --- a/Mage/src/mage/abilities/effects/common/LoseLifeTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/LoseLifeTargetEffect.java @@ -83,7 +83,7 @@ public class LoseLifeTargetEffect extends OneShotEffect { String message = amount.getMessage(); if (mode.getTargets().size() > 0) { - sb.append("Target ").append(mode.getTargets().get(0).getTargetName()); + sb.append("target ").append(mode.getTargets().get(0).getTargetName()); } else { sb.append("that player"); } diff --git a/Mage/src/mage/game/permanent/token/ZombieToken.java b/Mage/src/mage/game/permanent/token/ZombieToken.java index 6cd4982809..e64c978b46 100644 --- a/Mage/src/mage/game/permanent/token/ZombieToken.java +++ b/Mage/src/mage/game/permanent/token/ZombieToken.java @@ -30,7 +30,6 @@ package mage.game.permanent.token; import java.util.Random; import mage.MageInt; -import mage.ObjectColor; import mage.constants.CardType; /**