diff --git a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java index b1ba0793891..56c40601695 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java @@ -27,6 +27,7 @@ */ package mage.cards.c; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.AttachEffect; @@ -46,8 +47,6 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTarget; -import java.util.UUID; - /** * * @author BetaSteward @@ -55,11 +54,10 @@ import java.util.UUID; public class CurseOfOblivion extends CardImpl { public CurseOfOblivion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); this.subtype.add("Aura"); this.subtype.add("Curse"); - // Enchant player TargetPlayer target = new TargetPlayer(); this.getSpellAbility().addTarget(target); @@ -119,4 +117,4 @@ class CurseOfOblivionAbility extends TriggeredAbilityImpl { return "At the beginning of enchanted player's upkeep, that player exiles two cards from his or her graveyard."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/Dreamcatcher.java b/Mage.Sets/src/mage/cards/d/Dreamcatcher.java index a50450228e5..933381b2c6b 100644 --- a/Mage.Sets/src/mage/cards/d/Dreamcatcher.java +++ b/Mage.Sets/src/mage/cards/d/Dreamcatcher.java @@ -27,6 +27,7 @@ */ package mage.cards.d; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; @@ -37,8 +38,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.common.FilterSpiritOrArcaneCard; -import java.util.UUID; - /** * * @author LevelX2 @@ -46,15 +45,15 @@ import java.util.UUID; public class Dreamcatcher extends CardImpl { public Dreamcatcher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add("Spirit"); this.power = new MageInt(1); this.toughness = new MageInt(1); // Whenever you cast a Spirit or Arcane spell, you may sacrifice Dreamcatcher. If you do, draw a card. - Ability ability = new SpellCastControllerTriggeredAbility(new SacrificeSourceEffect(), new FilterSpiritOrArcaneCard(), true, - "Whenever you cast a Spirit or Arcane spell, you may sacrifice Dreamcatcher. If you do, draw a card."); + Ability ability = new SpellCastControllerTriggeredAbility(new SacrificeSourceEffect(), new FilterSpiritOrArcaneCard(), true, + "Whenever you cast a Spirit or Arcane spell, you may sacrifice {this}. If you do, draw a card."); ability.addEffect(new DrawCardSourceControllerEffect(1)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KhenraEternal.java b/Mage.Sets/src/mage/cards/k/KhenraEternal.java index 0a6fd8ab013..b5dc4b92a0d 100644 --- a/Mage.Sets/src/mage/cards/k/KhenraEternal.java +++ b/Mage.Sets/src/mage/cards/k/KhenraEternal.java @@ -1,16 +1,15 @@ package mage.cards.k; +import java.util.UUID; import mage.MageInt; import mage.abilities.keyword.AfflictAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import java.util.UUID; - public class KhenraEternal extends CardImpl { - public KhenraEternal(UUID ownerId, CardSetInfo cardSetInfo){ + public KhenraEternal(UUID ownerId, CardSetInfo cardSetInfo) { super(ownerId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); subtype.add("Zombie"); subtype.add("Jackal"); @@ -18,15 +17,16 @@ public class KhenraEternal extends CardImpl { power = new MageInt(2); toughness = new MageInt(2); + // Afflict 1 (Whenever this creature becomes blocked, defending player loses 1 life.) addAbility(new AfflictAbility(1)); } - public KhenraEternal(final KhenraEternal khenraEternal){ + public KhenraEternal(final KhenraEternal khenraEternal) { super(khenraEternal); } - public KhenraEternal copy(){ + public KhenraEternal copy() { return new KhenraEternal(this); } } diff --git a/Mage.Sets/src/mage/cards/l/LilianasDefeat.java b/Mage.Sets/src/mage/cards/l/LilianasDefeat.java index 0a2fbb3d4d7..81ba966a6ea 100644 --- a/Mage.Sets/src/mage/cards/l/LilianasDefeat.java +++ b/Mage.Sets/src/mage/cards/l/LilianasDefeat.java @@ -56,6 +56,7 @@ public class LilianasDefeat extends CardImpl { FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent("black creature or black planeswalker"); filter.add(new ColorPredicate(ObjectColor.BLACK)); // Destroy target black creature or black planeswalker. If that permanent was a Liliana planeswalker, her controller loses 3 life. + this.getSpellAbility().addEffect(new LilianasDefeatEffect()); this.getSpellAbility().addTarget(new TargetPermanent(filter)); } diff --git a/Mage.Sets/src/mage/cards/m/MaraudingBoneslasher.java b/Mage.Sets/src/mage/cards/m/MaraudingBoneslasher.java index 8b0ca34c2a3..80ae641bf6b 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingBoneslasher.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingBoneslasher.java @@ -29,20 +29,16 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.combat.CantBlockUnlessYouControlSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; /** * @@ -50,16 +46,24 @@ import mage.game.permanent.Permanent; */ public class MaraudingBoneslasher extends CardImpl { + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Zombie"); + + static { + filter.add(new SubtypePredicate(SubType.ZOMBIE)); + filter.add(new AnotherPredicate()); + } + public MaraudingBoneslasher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add("Zombie"); - this.subtype.add("Zombie"); + this.subtype.add("Minotaur"); this.power = new MageInt(3); this.toughness = new MageInt(3); // Marauding Boneslasher can't block unless you control another Zombie. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MaraudingBoneslasherRestrictionEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockUnlessYouControlSourceEffect(filter))); + } public MaraudingBoneslasher(final MaraudingBoneslasher card) { @@ -71,42 +75,3 @@ public class MaraudingBoneslasher extends CardImpl { return new MaraudingBoneslasher(this); } } - -class MaraudingBoneslasherRestrictionEffect extends RestrictionEffect { - - private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Zombie"); - - static { - filter.add(new SubtypePredicate(SubType.ZOMBIE)); - filter.add(new AnotherPredicate()); - } - - public MaraudingBoneslasherRestrictionEffect() { - super(Duration.WhileOnBattlefield); - - staticText = "{this} can't block unless you control another Zombie"; - } - - public MaraudingBoneslasherRestrictionEffect(final MaraudingBoneslasherRestrictionEffect effect) { - super(effect); - } - - @Override - public MaraudingBoneslasherRestrictionEffect copy() { - return new MaraudingBoneslasherRestrictionEffect(this); - } - - @Override - public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { - return false; - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.getId().equals(source.getSourceId()) - && game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == 0) { - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java b/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java new file mode 100644 index 00000000000..9a57e37f456 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java @@ -0,0 +1,119 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class TormentOfHailfire extends CardImpl { + + public TormentOfHailfire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}"); + + // Repeat the following process X times. Each opponent loses 3 life unless he or she sacrifices a nonland permanent or discards a card. + this.getSpellAbility().addEffect(new TormentOfHailfireEffect()); + + } + + public TormentOfHailfire(final TormentOfHailfire card) { + super(card); + } + + @Override + public TormentOfHailfire copy() { + return new TormentOfHailfire(this); + } +} + +class TormentOfHailfireEffect extends OneShotEffect { + + public TormentOfHailfireEffect() { + super(Outcome.LoseLife); + this.staticText = "Repeat the following process X times. Each opponent loses 3 life unless he or she sacrifices a nonland permanent or discards a card"; + } + + public TormentOfHailfireEffect(final TormentOfHailfireEffect effect) { + super(effect); + } + + @Override + public TormentOfHailfireEffect copy() { + return new TormentOfHailfireEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int repeat = source.getManaCosts().getX(); + for (int i = 0; i < repeat; i++) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, opponentId, game); + if (permanents > 0 && opponent.chooseUse(outcome, "Sacrifices a nonland permanent? (Iteration " + i + " of " + repeat + ")", + "Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) { + Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); + if (opponent.choose(outcome, target, source.getSourceId(), game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + continue; + } + } + } + if (!opponent.getHand().isEmpty() && opponent.chooseUse(outcome, "Discard a card? (Iteration " + i + " of " + repeat + ")", + "Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) { + opponent.discardOne(false, source, game); + continue; + } + opponent.loseLife(3, game, false); + } + } + + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java new file mode 100644 index 00000000000..b3811512f88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java @@ -0,0 +1,168 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class TormentOfScarabs extends CardImpl { + + public TormentOfScarabs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); + + this.subtype.add("Aura"); + this.subtype.add("Curse"); + + // Enchant player + TargetPlayer auraTarget = new TargetPlayer(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseLife)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of enchanted player's upkeep, that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card. + this.addAbility(new TormentOfScarabsAbility()); + } + + public TormentOfScarabs(final TormentOfScarabs card) { + super(card); + } + + @Override + public TormentOfScarabs copy() { + return new TormentOfScarabs(this); + } +} + +class TormentOfScarabsAbility extends TriggeredAbilityImpl { + + public TormentOfScarabsAbility() { + super(Zone.BATTLEFIELD, new TormentOfScarabsEffect()); + } + + public TormentOfScarabsAbility(final TormentOfScarabsAbility ability) { + super(ability); + } + + @Override + public TormentOfScarabsAbility copy() { + return new TormentOfScarabsAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.UPKEEP_STEP_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent enchantment = game.getPermanent(this.sourceId); + if (enchantment != null && enchantment.getAttachedTo() != null) { + Player player = game.getPlayer(enchantment.getAttachedTo()); + if (player != null && game.getActivePlayerId().equals(player.getId())) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "At the beginning of enchanted player's upkeep, that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card."; + } + +} + +class TormentOfScarabsEffect extends OneShotEffect { + + public TormentOfScarabsEffect() { + super(Outcome.LoseLife); + this.staticText = "that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card"; + } + + public TormentOfScarabsEffect(final TormentOfScarabsEffect effect) { + super(effect); + } + + @Override + public TormentOfScarabsEffect copy() { + return new TormentOfScarabsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player enchantedPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (enchantedPlayer != null) { + int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, enchantedPlayer.getId(), game); + if (permanents > 0 && enchantedPlayer.chooseUse(outcome, "Sacrifices a nonland permanent?", + "Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) { + Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); + if (enchantedPlayer.choose(outcome, target, source.getSourceId(), game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + return true; + } + } + } + if (!enchantedPlayer.getHand().isEmpty() && enchantedPlayer.chooseUse(outcome, "Discard a card?", + "Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) { + enchantedPlayer.discardOne(false, source, game); + return true; + } + enchantedPlayer.loseLife(3, game, false); + return true; + } + + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TormentOfVenom.java b/Mage.Sets/src/mage/cards/t/TormentOfVenom.java new file mode 100644 index 00000000000..d7d9e95610d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TormentOfVenom.java @@ -0,0 +1,118 @@ +/* + * 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.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class TormentOfVenom extends CardImpl { + + public TormentOfVenom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}{B}"); + + // Put three -1/-1 counters on target creature. Its controller loses 3 life unless he or she sacrifices another nonland permanent or discards a card. + this.getSpellAbility().addEffect(new TormentOfVenomEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public TormentOfVenom(final TormentOfVenom card) { + super(card); + } + + @Override + public TormentOfVenom copy() { + return new TormentOfVenom(this); + } +} + +class TormentOfVenomEffect extends OneShotEffect { + + public TormentOfVenomEffect() { + super(Outcome.LoseLife); + this.staticText = "Put three -1/-1 counters on target creature. Its controller loses 3 life unless he or she sacrifices another nonland permanent or discards a card"; + } + + public TormentOfVenomEffect(final TormentOfVenomEffect effect) { + super(effect); + } + + @Override + public TormentOfVenomEffect copy() { + return new TormentOfVenomEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (targetCreature != null) { + new AddCountersTargetEffect(CounterType.M1M1.createInstance(3)).apply(game, source); + Player controllingPlayer = game.getPlayer(targetCreature.getControllerId()); + if (controllingPlayer != null) { + int permanents = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_NON_LAND, controllingPlayer.getId(), game); + if (permanents > 0 && controllingPlayer.chooseUse(outcome, "Sacrifices a nonland permanent?", + "Otherwise you have to discard a card or lose 3 life.", "Sacrifice", "Discard or life loss", source, game)) { + Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); + if (controllingPlayer.choose(outcome, target, source.getSourceId(), game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + return true; + } + } + } + if (!controllingPlayer.getHand().isEmpty() && controllingPlayer.chooseUse(outcome, "Discard a card?", + "Otherwise you lose 3 life.", "Discard", "Lose 3 life", source, game)) { + controllingPlayer.discardOne(false, source, game); + return true; + } + controllingPlayer.loseLife(3, game, false); + return true; + } + } + + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MauraudingBoneslasher.java b/Mage.Sets/src/mage/cards/w/WaspOfTheBitterEnd.java similarity index 55% rename from Mage.Sets/src/mage/cards/m/MauraudingBoneslasher.java rename to Mage.Sets/src/mage/cards/w/WaspOfTheBitterEnd.java index a4dc03a4c24..e68e874b7f6 100644 --- a/Mage.Sets/src/mage/cards/m/MauraudingBoneslasher.java +++ b/Mage.Sets/src/mage/cards/w/WaspOfTheBitterEnd.java @@ -25,53 +25,62 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.cards.m; +package mage.cards.w; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.combat.CantBlockUnlessYouControlSourceEffect; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetCreaturePermanent; /** * * @author LevelX2 */ -public class MauraudingBoneslasher extends CardImpl { +public class WaspOfTheBitterEnd extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Zombie"); + private static final FilterSpell filter = new FilterSpell("a Bolas planeswalker spell"); static { - filter.add(new SubtypePredicate(SubType.ZOMBIE)); - filter.add(new AnotherPredicate()); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.BOLAS)); } - public MauraudingBoneslasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + public WaspOfTheBitterEnd(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); - this.subtype.add("Zombie"); - this.subtype.add("Minotaur"); - this.power = new MageInt(3); - this.toughness = new MageInt(3); + this.subtype.add("Insect"); + this.subtype.add("Horror"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); - // Marauding Boneslasher can't block unless you control another Zombie. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockUnlessYouControlSourceEffect(filter))); + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever you cast a Bolas planeswalker spell, you may sacrifice Wasp of the Bitter End. If you do, destroy target creature. + Ability ability = new SpellCastControllerTriggeredAbility(new SacrificeSourceEffect(), filter, true, + "Whenever you cast a Bolas planeswalker spell, you may sacrifice {this}. If you do, destroy target creature."); + ability.addEffect(new DestroyTargetEffect()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); } - public MauraudingBoneslasher(final MauraudingBoneslasher card) { + public WaspOfTheBitterEnd(final WaspOfTheBitterEnd card) { super(card); } @Override - public MauraudingBoneslasher copy() { - return new MauraudingBoneslasher(this); + public WaspOfTheBitterEnd copy() { + return new WaspOfTheBitterEnd(this); } } diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index dfa95e22189..619f93c3d80 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -27,6 +27,8 @@ */ package mage.sets; +import java.util.ArrayList; +import java.util.List; import mage.cards.ExpansionSet; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; @@ -34,9 +36,6 @@ import mage.cards.repository.CardRepository; import mage.constants.Rarity; import mage.constants.SetType; -import java.util.ArrayList; -import java.util.List; - /** * @author fireshoes */ @@ -79,14 +78,13 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Desert of the True", 174, Rarity.COMMON, mage.cards.d.DesertOfTheTrue.class)); cards.add(new SetCardInfo("Doomfall", 62, Rarity.UNCOMMON, mage.cards.d.Doomfall.class)); cards.add(new SetCardInfo("Dreamstealer", 63, Rarity.RARE, mage.cards.d.Dreamstealer.class)); - cards.add(new SetCardInfo("Hour of Glory", 065, Rarity.RARE, mage.cards.h.HourOfGlory.class)); + cards.add(new SetCardInfo("Hour of Glory", 65, Rarity.RARE, mage.cards.h.HourOfGlory.class)); cards.add(new SetCardInfo("Hour of Revelation", 15, Rarity.RARE, mage.cards.h.HourOfRevelation.class)); cards.add(new SetCardInfo("Inferno Jet", 99, Rarity.UNCOMMON, mage.cards.i.InfernoJet.class)); cards.add(new SetCardInfo("Khenra Eternal", 66, Rarity.COMMON, mage.cards.k.KhenraEternal.class)); cards.add(new SetCardInfo("Khenra Scrapper", 100, Rarity.COMMON, mage.cards.k.KhenraScrapper.class)); cards.add(new SetCardInfo("Liliana's Defeat", 68, Rarity.UNCOMMON, mage.cards.l.LilianasDefeat.class)); cards.add(new SetCardInfo("Marauding Boneslasher", 70, Rarity.COMMON, mage.cards.m.MaraudingBoneslasher.class)); - cards.add(new SetCardInfo("Maurauding Boneslasher", 70, Rarity.COMMON, mage.cards.m.MauraudingBoneslasher.class)); cards.add(new SetCardInfo("Nicol Bolas, God-Pharaoh", 140, Rarity.MYTHIC, mage.cards.n.NicolBolasGodPharaoh.class)); cards.add(new SetCardInfo("Open Fire", 105, Rarity.COMMON, mage.cards.o.OpenFire.class)); cards.add(new SetCardInfo("Proven Combatant", 42, Rarity.COMMON, mage.cards.p.ProvenCombatant.class)); @@ -97,9 +95,13 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Solemnity", 22, Rarity.RARE, mage.cards.s.Solemnity.class)); cards.add(new SetCardInfo("Steadfast Sentinel", 24, Rarity.COMMON, mage.cards.s.SteadfastSentinel.class)); cards.add(new SetCardInfo("Supreme Will", 49, Rarity.UNCOMMON, mage.cards.s.SupremeWill.class)); + cards.add(new SetCardInfo("Torment of Hailfire", 77, Rarity.RARE, mage.cards.t.TormentOfHailfire.class)); + cards.add(new SetCardInfo("Torment of Scarabs", 78, Rarity.UNCOMMON, mage.cards.t.TormentOfScarabs.class)); + cards.add(new SetCardInfo("Torment of Venom", 79, Rarity.COMMON, mage.cards.t.TormentOfVenom.class)); cards.add(new SetCardInfo("Unesh, Criosphinx Sovereign", 52, Rarity.MYTHIC, mage.cards.u.UneshCriosphinxSovereign.class)); cards.add(new SetCardInfo("Visage of Bolas", 208, Rarity.RARE, mage.cards.v.VisageOfBolas.class)); cards.add(new SetCardInfo("Vizier of the True", 28, Rarity.UNCOMMON, mage.cards.v.VizierOfTheTrue.class)); + cards.add(new SetCardInfo("Wasp of the Bitter End", 206, Rarity.UNCOMMON, mage.cards.w.WaspOfTheBitterEnd.class)); cards.add(new SetCardInfo("Wildfire Eternal", 109, Rarity.RARE, mage.cards.w.WildfireEternal.class)); cards.add(new SetCardInfo("Woodland Stream", 204, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); cards.add(new SetCardInfo("Zealot of the God-Pharaoh", 207, Rarity.COMMON, mage.cards.z.ZealotOfTheGodPharaoh.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/AfflictAbility.java b/Mage/src/main/java/mage/abilities/keyword/AfflictAbility.java index c641d22d5b1..24398c7eef4 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AfflictAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AfflictAbility.java @@ -12,13 +12,19 @@ public class AfflictAbility extends BecomesBlockedTriggeredAbility { return new AfflictAbility(this); } - public AfflictAbility(int amount){ - super(new LoseLifeDefendingPlayerEffect(amount, true), false); + public AfflictAbility(int amount) { + super(new LoseLifeDefendingPlayerEffect(amount, true) + .setText("Afflict " + amount + "(Whenever this creature becomes blocked, defending player loses " + amount + " life.)"), false); + lifeLoss = amount; } - public AfflictAbility(final AfflictAbility afflictAbility){ + public AfflictAbility(final AfflictAbility afflictAbility) { super(afflictAbility); lifeLoss = afflictAbility.lifeLoss; } + @Override + public String getRule() { + return "Afflict " + lifeLoss + "(Whenever this creature becomes blocked, defending player loses " + lifeLoss + " life.)"; + } } diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index d6146142c07..6c54add9735 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -15,6 +15,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreatureSpell; import mage.filter.common.FilterNonlandCard; +import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; @@ -27,23 +28,28 @@ import mage.filter.predicate.permanent.TokenPredicate; */ public final class StaticFilters { - public static final FilterCreaturePermanent FILTER_ARTIFACT_CREATURE_PERMANENT = new FilterArtifactCreaturePermanent(); - public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature"); - public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("artifact or creature you control"); - public static final FilterControlledPermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control"); - public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_ANOTHER_CREATURE = new FilterControlledCreaturePermanent("another creature"); - public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT = new FilterControlledArtifactPermanent(); public static final FilterArtifactCard FILTER_CARD_ARTIFACT = new FilterArtifactCard(); public static final FilterNonlandCard FILTER_CARD_NON_LAND = new FilterNonlandCard(); public static final FilterNonlandCard FILTER_CARD_A_NON_LAND = new FilterNonlandCard("a nonland card"); public static final FilterCard FILTER_CARD_ARTIFACT_OR_CREATURE = new FilterCard("artifact or creature card"); + public static final FilterCreaturePermanent FILTER_ARTIFACT_CREATURE_PERMANENT = new FilterArtifactCreaturePermanent(); + public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature"); + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT = new FilterControlledArtifactPermanent(); + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("artifact or creature you control"); + + public static final FilterControlledPermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control"); + public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_ANOTHER_CREATURE = new FilterControlledCreaturePermanent("another creature"); + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_NON_LAND = new FilterControlledPermanent("nonland permanent"); + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE = new FilterCreaturePermanent(); public static final FilterCreaturePermanent FILTER_PERMANENT_A_CREATURE = new FilterCreaturePermanent("a creature"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES = new FilterCreaturePermanent("creatures"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_GOBLINS = new FilterCreaturePermanent(SubType.GOBLIN, "Goblin creatures"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "Sliver creatures"); + public static final FilterPermanent FILTER_PERMANENT_NON_LAND = new FilterNonlandPermanent(); + public static final FilterCreatureSpell FILTER_SPELL_A_CREATURE = new FilterCreatureSpell("a creature spell"); public static final FilterSpell FILTER_SPELL_NON_CREATURE = (FilterSpell) new FilterSpell("noncreature spell").add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); @@ -53,6 +59,8 @@ public final class StaticFilters { public static final FilterPermanent FILTER_ATTACKING_CREATURES = new FilterCreaturePermanent("attacking creatures"); static { + FILTER_CONTROLLED_PERMANENT_NON_LAND.add( + Predicates.not(new CardTypePredicate(CardType.LAND))); FILTER_CREATURE_TOKENS.add(new TokenPredicate()); FILTER_ATTACKING_CREATURES.add(new AttackingPredicate());