diff --git a/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java b/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java new file mode 100644 index 00000000000..b7a26eccdc4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class AnZerrinRuins extends CardImpl { + + public AnZerrinRuins(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); + + // As An-Zerrin Ruins enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.UnboostCreature))); + + // Creatures of the chosen type don't untap during their controllers' untap steps. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AnZerrinRuinsDontUntapEffect())); + } + + public AnZerrinRuins(final AnZerrinRuins card) { + super(card); + } + + @Override + public AnZerrinRuins copy() { + return new AnZerrinRuins(this); + } +} + +class AnZerrinRuinsDontUntapEffect extends DontUntapInControllersUntapStepAllEffect { + + public AnZerrinRuinsDontUntapEffect() { + super(Duration.WhileOnBattlefield, TargetController.ANY, new FilterCreaturePermanent()); + } + + public AnZerrinRuinsDontUntapEffect(final AnZerrinRuinsDontUntapEffect effect) { + super(effect); + } + + @Override + public AnZerrinRuinsDontUntapEffect copy() { + return new AnZerrinRuinsDontUntapEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + Permanent sourcePerm = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && sourcePerm != null) { + SubType subtype = (SubType) game.getState().getValue(sourcePerm.getId() + "_type"); + if (permanent.getSubtype(game).contains(subtype)) { + return true; + } + } + } + return false; + } + + @Override + public String getText(Mode mode) { + return "Creatures of the chosen type don't untap during their controllers' untap steps."; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AncientHellkite.java b/Mage.Sets/src/mage/cards/a/AncientHellkite.java index a44e3c9817f..bb830ed9732 100644 --- a/Mage.Sets/src/mage/cards/a/AncientHellkite.java +++ b/Mage.Sets/src/mage/cards/a/AncientHellkite.java @@ -25,28 +25,24 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.condition.common.SourceAttackingCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ColoredManaSymbol; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; /** @@ -55,19 +51,37 @@ import mage.target.common.TargetCreaturePermanent; */ public class AncientHellkite extends CardImpl { + private final UUID originalId; + public AncientHellkite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(6); this.toughness = new MageInt(6); this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new AncientHellkiteAbility()); + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}"), SourceAttackingCondition.instance); + ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); + originalId = ability.getOriginalId(); + this.addAbility(ability); } public AncientHellkite(final AncientHellkite card) { super(card); + this.originalId = card.originalId; + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability.getOriginalId().equals(originalId)) { + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); + filter.add(new ControllerIdPredicate(defenderId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(filter); + ability.addTarget(target); + } } @Override @@ -76,71 +90,3 @@ public class AncientHellkite extends CardImpl { } } - -class AncientHellkiteAbility extends ActivatedAbilityImpl { - - private static final FilterCreaturePermanent filterTemplate = new FilterCreaturePermanent("creature defending player controls"); - - public AncientHellkiteAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); - addCost(new AncientHellkiteCost()); - addManaCost(new ColoredManaCost(ColoredManaSymbol.R)); - addTarget(new TargetCreaturePermanent(filterTemplate)); - } - - public AncientHellkiteAbility(final AncientHellkiteAbility ability) { - super(ability); - } - - @Override - public AncientHellkiteAbility copy() { - return new AncientHellkiteAbility(this); - } - - @Override - public boolean activate(Game game, boolean noMana) { - UUID defenderId = game.getCombat().getDefenderId(sourceId); - if (defenderId != null) { - FilterCreaturePermanent filter = filterTemplate.copy(); - filter.add(new ControllerIdPredicate(defenderId)); - - this.getTargets().clear(); - TargetCreaturePermanent target = new TargetCreaturePermanent(filter); - this.addTarget(target); - return super.activate(game, noMana); - } - return false; - } -} - -class AncientHellkiteCost extends CostImpl { - - public AncientHellkiteCost() { - this.text = "Activate this ability only if Ancient Hellkite is attacking"; - } - - public AncientHellkiteCost(final AncientHellkiteCost cost) { - super(cost); - } - - @Override - public AncientHellkiteCost copy() { - return new AncientHellkiteCost(this); - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.isAttacking()) { - return true; - } - return false; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - this.paid = true; - return paid; - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java b/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java index 0ff4dc40918..e443ace2d94 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java +++ b/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java @@ -29,13 +29,13 @@ package mage.cards.b; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; @@ -43,6 +43,7 @@ import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; @@ -55,7 +56,7 @@ import mage.players.Player; public class BrutalDeceiver extends CardImpl { public BrutalDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); @@ -65,9 +66,7 @@ public class BrutalDeceiver extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. - Ability ability = new BrutalDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}")); - ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BrutalDeceiverEffect(), new ManaCostsImpl("{2}"))); } public BrutalDeceiver(final BrutalDeceiver card) { @@ -80,38 +79,39 @@ public class BrutalDeceiver extends CardImpl { } } -class BrutalDeceiverAbility extends LimitedTimesPerTurnActivatedAbility { +class BrutalDeceiverEffect extends OneShotEffect { - public BrutalDeceiverAbility(Zone zone, Effect effect, Cost cost) { - super(zone, effect, cost); + public BrutalDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn"; } - public BrutalDeceiverAbility(BrutalDeceiverAbility ability) { - super(ability); + public BrutalDeceiverEffect(final BrutalDeceiverEffect effect) { + super(effect); } @Override - public BrutalDeceiverAbility copy() { - return new BrutalDeceiverAbility(this); + public BrutalDeceiverEffect copy() { + return new BrutalDeceiverEffect(this); } @Override - public boolean checkIfClause(Game game) { - Player player = game.getPlayer(this.getControllerId()); - if (player != null) { + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { Cards cards = new CardsImpl(); - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - player.revealCards("Brutal Deceiver", cards, game); - if (card != null && card.isLand()) { - return true; + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(1, 0, Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), source); + } } + return true; } return false; } - - @Override - public String getRule() { - return "{2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. Activate this ability only once each turn."; - } } diff --git a/Mage.Sets/src/mage/cards/c/CabalInquisitor.java b/Mage.Sets/src/mage/cards/c/CabalInquisitor.java index ded5d90a146..43f4de72c2e 100644 --- a/Mage.Sets/src/mage/cards/c/CabalInquisitor.java +++ b/Mage.Sets/src/mage/cards/c/CabalInquisitor.java @@ -52,11 +52,10 @@ import mage.target.common.TargetCardInYourGraveyard; * * @author cbt33 */ - public class CabalInquisitor extends CardImpl { public CabalInquisitor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.MINION); @@ -82,11 +81,8 @@ public class CabalInquisitor extends CardImpl { } } - class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl { - private Condition condition; - private static final Effects emptyEffects = new Effects(); public ActivateAsSorceryConditionalActivatedAbility(Zone zone, Effect effect, ManaCosts cost, Condition condition) { @@ -95,10 +91,8 @@ class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl timing = TimingRule.SORCERY; } - public ActivateAsSorceryConditionalActivatedAbility(final ActivateAsSorceryConditionalActivatedAbility ability) { super(ability); - this.condition = ability.condition; } @Override @@ -109,14 +103,6 @@ class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public ActivateAsSorceryConditionalActivatedAbility copy() { return new ActivateAsSorceryConditionalActivatedAbility(this); diff --git a/Mage.Sets/src/mage/cards/c/CallousDeceiver.java b/Mage.Sets/src/mage/cards/c/CallousDeceiver.java index 4aa3f68801a..03c905e245a 100644 --- a/Mage.Sets/src/mage/cards/c/CallousDeceiver.java +++ b/Mage.Sets/src/mage/cards/c/CallousDeceiver.java @@ -56,7 +56,7 @@ import mage.players.Player; public class CallousDeceiver extends CardImpl { public CallousDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/c/ChronatogTotem.java b/Mage.Sets/src/mage/cards/c/ChronatogTotem.java index 3633454e292..2cb60a672e0 100644 --- a/Mage.Sets/src/mage/cards/c/ChronatogTotem.java +++ b/Mage.Sets/src/mage/cards/c/ChronatogTotem.java @@ -59,14 +59,14 @@ import mage.game.permanent.token.Token; public class ChronatogTotem extends CardImpl { public ChronatogTotem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {tap}: Add {U} to your mana pool. this.addAbility(new BlueManaAbility()); - + // {1}{U}: Chronatog Totem becomes a 1/2 blue Atog artifact creature until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new ChronatogTotemToken(), "", Duration.EndOfTurn), new ManaCostsImpl<>("{1}{U}"))); - + // {0}: Chronatog Totem gets +3/+3 until end of turn. You skip your next turn. Activate this ability only once each turn and only if Chronatog Totem is a creature. Ability ability = new ChronatogTotemAbility( Zone.BATTLEFIELD, @@ -91,8 +91,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { private static final Effects emptyEffects = new Effects(); - private final Condition condition; - public ChronatogTotemAbility(Zone zone, Effect effect, Cost cost, Condition condition) { super(zone, effect, cost); this.condition = condition; @@ -100,7 +98,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { public ChronatogTotemAbility(ChronatogTotemAbility ability) { super(ability); - this.condition = ability.condition; } @Override @@ -111,14 +108,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public ChronatogTotemAbility copy() { return new ChronatogTotemAbility(this); diff --git a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java index ed6b1ef8e38..dd515075b0b 100644 --- a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java +++ b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java @@ -29,16 +29,17 @@ package mage.cards.c; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.TrampleAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.SubType; @@ -55,7 +56,7 @@ import mage.players.Player; public class CruelDeceiver extends CardImpl { public CruelDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); @@ -82,7 +83,7 @@ class CruelDeceiverEffect extends OneShotEffect { public CruelDeceiverEffect() { super(Outcome.AddAbility); - this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn"; + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gains \"Whenever Cruel Deceiver deals damage to a creature, destroy that creature\" until end of turn"; } public CruelDeceiverEffect(final CruelDeceiverEffect effect) { @@ -96,15 +97,17 @@ class CruelDeceiverEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { Cards cards = new CardsImpl(); - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - player.revealCards("Cruel Deceiver", cards, game); - if (card != null && card.isLand()) { - game.addEffect(new BoostSourceEffect(2,2,Duration.EndOfTurn), source); - game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(),Duration.EndOfTurn), source); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new GainAbilitySourceEffect(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(true), false, false, true), Duration.EndOfTurn), source); + } } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java new file mode 100644 index 00000000000..13b6ae13b3f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.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.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public class DeathgorgeScavenger extends CardImpl { + + public DeathgorgeScavenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DeathgorgeScavengerEffect(), true); + ability.addTarget(new TargetCardInGraveyard()); + this.addAbility(ability); + } + + public DeathgorgeScavenger(final DeathgorgeScavenger card) { + super(card); + } + + @Override + public DeathgorgeScavenger copy() { + return new DeathgorgeScavenger(this); + } +} + +class DeathgorgeScavengerEffect extends OneShotEffect { + + public DeathgorgeScavengerEffect() { + super(Outcome.Benefit); + this.staticText = "exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, {this} gets +1/+1 until end of turn"; + } + + public DeathgorgeScavengerEffect(final DeathgorgeScavengerEffect effect) { + super(effect); + } + + @Override + public DeathgorgeScavengerEffect copy() { + return new DeathgorgeScavengerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + if (card.isCreature()) { + controller.gainLife(2, game); + } else { + new BoostSourceEffect(1, 1, Duration.EndOfTurn).apply(game, source); + } + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java b/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java new file mode 100644 index 00000000000..0587f17b366 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.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.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class EmissaryOfSunrise extends CardImpl { + + public EmissaryOfSunrise(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // When Emissary of Sunrise enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public EmissaryOfSunrise(final EmissaryOfSunrise card) { + super(card); + } + + @Override + public EmissaryOfSunrise copy() { + return new EmissaryOfSunrise(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EnergyStorm.java b/Mage.Sets/src/mage/cards/e/EnergyStorm.java new file mode 100644 index 00000000000..3bf51c4a3f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnergyStorm.java @@ -0,0 +1,82 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect; +import mage.abilities.effects.common.PreventAllDamageByAllObjectsEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; + +/** + * + * @author TheElk801 + */ +public class EnergyStorm extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public EnergyStorm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // Prevent all damage that would be dealt by instant and sorcery spells. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new PreventAllDamageByAllObjectsEffect(StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELLS, Duration.WhileOnBattlefield, false) + )); + + // Creatures with flying don't untap during their controllers' untap steps. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter))); + } + + public EnergyStorm(final EnergyStorm card) { + super(card); + } + + @Override + public EnergyStorm copy() { + return new EnergyStorm(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java index 69211f6845d..13c09f8abda 100644 --- a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java +++ b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java @@ -27,19 +27,19 @@ */ package mage.cards.e; -import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; 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.target.common.TargetCardInLibrary; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; /** * @@ -48,10 +48,15 @@ import java.util.UUID; public class EvolvingWilds extends CardImpl { public EvolvingWilds(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); // {T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library. - this.addAbility(new EvolvingWildsAbility()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public EvolvingWilds(final EvolvingWilds card) { @@ -64,24 +69,3 @@ public class EvolvingWilds extends CardImpl { } } - -class EvolvingWildsAbility extends ActivatedAbilityImpl { - - public EvolvingWildsAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new SacrificeSourceCost()); - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - addEffect(new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay)); - } - - public EvolvingWildsAbility(final EvolvingWildsAbility ability) { - super(ability); - } - - @Override - public EvolvingWildsAbility copy() { - return new EvolvingWildsAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/f/FeralDeceiver.java b/Mage.Sets/src/mage/cards/f/FeralDeceiver.java index c590aced713..5bde2e76fc3 100644 --- a/Mage.Sets/src/mage/cards/f/FeralDeceiver.java +++ b/Mage.Sets/src/mage/cards/f/FeralDeceiver.java @@ -29,21 +29,29 @@ package mage.cards.f; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.FeralDeceiverAbility; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; /** * @@ -52,19 +60,17 @@ import mage.constants.Zone; public class FeralDeceiver extends CardImpl { public FeralDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(3); this.toughness = new MageInt(2); // {1}: Look at the top card of your library. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn. - Ability ability = new FeralDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2,2,Duration.EndOfTurn), new ManaCostsImpl("{2}")); - ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(),Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new FeralDeceiverEffect(), new ManaCostsImpl("{2}"))); } public FeralDeceiver(final FeralDeceiver card) { @@ -77,3 +83,39 @@ public class FeralDeceiver extends CardImpl { } } +class FeralDeceiverEffect extends OneShotEffect { + + public FeralDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn"; + } + + public FeralDeceiverEffect(final FeralDeceiverEffect effect) { + super(effect); + } + + @Override + public FeralDeceiverEffect copy() { + return new FeralDeceiverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(2, 2, Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java new file mode 100644 index 00000000000..ccd0cc0f343 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java @@ -0,0 +1,134 @@ +/* + * 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.f; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class FieldOfRuin extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("nonbasic land an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); + } + + public FieldOfRuin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {2}, {T}, Sacrifice Field of Ruin: Destroy target nonbasic land an opponent controls. Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost()); + ability.addCost(new ManaCostsImpl("{2}")); + ability.addCost(new SacrificeSourceCost()); + ability.addEffect(new FieldOfRuinEffect()); + ability.addTarget(new TargetLandPermanent(filter)); + } + + public FieldOfRuin(final FieldOfRuin card) { + super(card); + } + + @Override + public FieldOfRuin copy() { + return new FieldOfRuin(this); + } +} + +class FieldOfRuinEffect extends OneShotEffect { + + FieldOfRuinEffect() { + super(Outcome.Benefit); + this.staticText = "Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library."; + } + + FieldOfRuinEffect(final FieldOfRuinEffect effect) { + super(effect); + } + + @Override + public FieldOfRuinEffect copy() { + return new FieldOfRuinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.searchLibrary(target, game)) { + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); + } + + } + player.shuffleLibrary(source, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GargoyleCastle.java b/Mage.Sets/src/mage/cards/g/GargoyleCastle.java index 69ab8a9efa9..56ec46d63cb 100644 --- a/Mage.Sets/src/mage/cards/g/GargoyleCastle.java +++ b/Mage.Sets/src/mage/cards/g/GargoyleCastle.java @@ -28,10 +28,11 @@ package mage.cards.g; import java.util.UUID; -import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; @@ -52,7 +53,13 @@ public class GargoyleCastle extends CardImpl { this.addAbility(new ColorlessManaAbility()); // {T}, {5}, Sacrifice Gargoyle Castle: Put a 3/4 colorless Gargoyle artifact creature token with flying onto the battlefield. - this.addAbility(new GargoyleCastleAbility()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new CreateTokenEffect(new GargoyleToken()), + new ManaCostsImpl("{5}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public GargoyleCastle(final GargoyleCastle card) { @@ -64,25 +71,4 @@ public class GargoyleCastle extends CardImpl { return new GargoyleCastle(this); } -} - -class GargoyleCastleAbility extends ActivatedAbilityImpl { - - public GargoyleCastleAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new GenericManaCost(5)); - addCost(new SacrificeSourceCost()); - addEffect(new CreateTokenEffect(new GargoyleToken())); - } - - public GargoyleCastleAbility(final GargoyleCastleAbility ability) { - super(ability); - } - - @Override - public GargoyleCastleAbility copy() { - return new GargoyleCastleAbility(this); - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java b/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java index 41b3e883e15..c03cd462e13 100644 --- a/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java +++ b/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java @@ -65,7 +65,7 @@ public class GroundlingPouncer extends CardImpl { } public GroundlingPouncer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}"); this.subtype.add(SubType.FAERIE); this.power = new MageInt(2); @@ -97,7 +97,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { private static final Effects emptyEffects = new Effects(); - private final Condition condition; private final String ruleText; public GroundlingPouncerAbility(Zone zone, Effect effect, Cost cost, Condition condition, String rule) { @@ -108,7 +107,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { public GroundlingPouncerAbility(GroundlingPouncerAbility ability) { super(ability); - this.condition = ability.condition; this.ruleText = ability.ruleText; } @@ -120,14 +118,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public GroundlingPouncerAbility copy() { return new GroundlingPouncerAbility(this); diff --git a/Mage.Sets/src/mage/cards/g/GuidedPassage.java b/Mage.Sets/src/mage/cards/g/GuidedPassage.java new file mode 100644 index 00000000000..fb04a3237b5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GuidedPassage.java @@ -0,0 +1,149 @@ +/* + * 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.g; + +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterLandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class GuidedPassage extends CardImpl { + + public GuidedPassage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{R}{G}"); + + // Reveal the cards in your library. An opponent chooses from among them a creature card, a land card, and a noncreature, nonland card. You put the chosen cards into your hand. Then shuffle your library. + this.getSpellAbility().addEffect(new GuidedPassageEffect()); + } + + public GuidedPassage(final GuidedPassage card) { + super(card); + } + + @Override + public GuidedPassage copy() { + return new GuidedPassage(this); + } +} + +class GuidedPassageEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("noncreature, nonland card"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + } + + GuidedPassageEffect() { + super(Outcome.Benefit); + this.staticText = "Reveal the cards in your library. An opponent chooses from among them a creature card, a land card, and a noncreature, nonland card. You put the chosen cards into your hand. Then shuffle your library."; + } + + GuidedPassageEffect(final GuidedPassageEffect effect) { + super(effect); + } + + @Override + public GuidedPassageEffect copy() { + return new GuidedPassageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + int libSize = controller.getLibrary().size(); + if (libSize == 0) { + controller.shuffleLibrary(source, game); + return true; + } + CardsImpl cards = new CardsImpl(); + cards.addAll(controller.getLibrary().getTopCards(game, libSize)); + controller.revealCards(sourceObject.getIdName(), cards, game); + + Player opponent; + Set opponents = game.getOpponents(controller.getId()); + if (opponents.size() == 1) { + opponent = game.getPlayer(opponents.iterator().next()); + } else { + Target target = new TargetOpponent(true); + controller.chooseTarget(Outcome.Detriment, target, source, game); + opponent = game.getPlayer(target.getFirstTarget()); + } + TargetCard target1 = new TargetCard(1, Zone.LIBRARY, new FilterCreatureCard()); + TargetCard target2 = new TargetCard(1, Zone.LIBRARY, new FilterLandCard()); + TargetCard target3 = new TargetCard(1, Zone.LIBRARY, new FilterCard(filter)); + opponent.chooseTarget(Outcome.Detriment, cards, target1, source, game); + opponent.chooseTarget(Outcome.Detriment, cards, target2, source, game); + opponent.chooseTarget(Outcome.Detriment, cards, target3, source, game); + Cards cardsToHand = new CardsImpl(); + Card cardToHand; + cardToHand = game.getCard(target1.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + cardToHand = game.getCard(target2.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + cardToHand = game.getCard(target3.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + controller.moveCards(cardsToHand, Zone.HAND, source, game); + controller.shuffleLibrary(source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HarshDeceiver.java b/Mage.Sets/src/mage/cards/h/HarshDeceiver.java index 6debef53fae..af887e3e3b8 100644 --- a/Mage.Sets/src/mage/cards/h/HarshDeceiver.java +++ b/Mage.Sets/src/mage/cards/h/HarshDeceiver.java @@ -29,20 +29,28 @@ package mage.cards.h; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.FeralDeceiverAbility; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; /** * @@ -51,19 +59,17 @@ import mage.constants.Zone; public class HarshDeceiver extends CardImpl { public HarshDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(1); this.toughness = new MageInt(4); // {1}: Look at the top card of your library. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, untap {this} and it gets +1/+1 until end of turn. - Ability ability = new FeralDeceiverAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new ManaCostsImpl("{2}")); - ability.addEffect(new BoostSourceEffect(1,1,Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new HarshDeceiverEffect(), new ManaCostsImpl("{2}"))); } public HarshDeceiver(final HarshDeceiver card) { @@ -75,3 +81,40 @@ public class HarshDeceiver extends CardImpl { return new HarshDeceiver(this); } } + +class HarshDeceiverEffect extends OneShotEffect { + + public HarshDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, untap {this} and it gets +1/+1 until end of turn"; + } + + public HarshDeceiverEffect(final HarshDeceiverEffect effect) { + super(effect); + } + + @Override + public HarshDeceiverEffect copy() { + return new HarshDeceiverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + new UntapSourceEffect().apply(game, source); + game.addEffect(new BoostSourceEffect(1, 1, Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InnerSanctum.java b/Mage.Sets/src/mage/cards/i/InnerSanctum.java new file mode 100644 index 00000000000..4f9c90ffa69 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InnerSanctum.java @@ -0,0 +1,68 @@ +/* + * 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.i; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.PreventAllDamageToAllEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreatureInPlay; + +/** + * + * @author TheElk801 + */ +public class InnerSanctum extends CardImpl { + + public InnerSanctum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); + + // Cumulative upkeep-Pay 2 life. + this.addAbility(new CumulativeUpkeepAbility(new PayLifeCost(2))); + + // Prevent all damage that would be dealt to creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, new FilterControlledCreatureInPlay("creatures you control")) + )); + } + + public InnerSanctum(final InnerSanctum card) { + super(card); + } + + @Override + public InnerSanctum copy() { + return new InnerSanctum(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KyrenToy.java b/Mage.Sets/src/mage/cards/k/KyrenToy.java index dd757a25c09..0dc4decc0c0 100644 --- a/Mage.Sets/src/mage/cards/k/KyrenToy.java +++ b/Mage.Sets/src/mage/cards/k/KyrenToy.java @@ -53,7 +53,7 @@ import mage.players.Player; public class KyrenToy extends CardImpl { public KyrenToy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {1}, {T}: Put a charge counter on Kyren Toy. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance(1)), new GenericManaCost(1)); @@ -95,7 +95,7 @@ public class KyrenToy extends CardImpl { KyrenToyManaEffect() { super(); - staticText = "Add X mana of {C} to your mana pool, and then add {C} to your mana pool"; + staticText = "Add an amount of {C} to your mana pool equal to X plus one"; } KyrenToyManaEffect(final KyrenToyManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java index 6c011ea8f05..7f607f32f94 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java +++ b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java @@ -30,8 +30,7 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreatureExploresTriggeredAbility; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.constants.SubType; import mage.cards.CardImpl; @@ -39,12 +38,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; /** @@ -53,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class LurkingChupacabra extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); @@ -68,7 +63,7 @@ public class LurkingChupacabra extends CardImpl { this.toughness = new MageInt(3); // Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn - Ability ability = new LurkingChupacabraTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); + Ability ability = new CreatureExploresTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); ability.addTarget(new TargetCreaturePermanent(filter)); } @@ -81,38 +76,3 @@ public class LurkingChupacabra extends CardImpl { return new LurkingChupacabra(this); } } - -class LurkingChupacabraTriggeredAbility extends TriggeredAbilityImpl { - - LurkingChupacabraTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect, false); - } - - LurkingChupacabraTriggeredAbility(final LurkingChupacabraTriggeredAbility effect) { - super(effect); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.EXPLORED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (creature != null) { - return creature.getControllerId().equals(controllerId); - } - return false; - } - - @Override - public LurkingChupacabraTriggeredAbility copy() { - return new LurkingChupacabraTriggeredAbility(this); - } - - @Override - public String getRule() { - return "Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn"; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java index 4e4b5cb0505..12657930276 100644 --- a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java +++ b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java @@ -27,21 +27,14 @@ */ package mage.cards.m; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; +import mage.abilities.ActivatedAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -54,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.constants.SuperType; import mage.constants.TargetController; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterCard; @@ -63,15 +55,11 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.other.CounterCardPredicate; import mage.filter.predicate.other.OwnerPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; -import mage.game.stack.StackAbility; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInYourGraveyard; -import mage.watchers.Watcher; /** * @@ -93,8 +81,7 @@ public class MairsilThePretender extends CardImpl { // Mairsil, the Pretender has all activated abilities of all cards you own in exile with cage counters on them. You may activate each of those abilities only once each turn. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new MairsilThePretenderGainAbilitiesEffect()); - ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); - this.addAbility(ability, new MairsilThePretenderWatcher()); + this.addAbility(ability); } public MairsilThePretender(final MairsilThePretender card) { @@ -182,11 +169,8 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { if (filter.match(card, game)) { for (Ability ability : card.getAbilities()) { if (ability instanceof ActivatedAbility) { - UUID originaId = ability.getId(); - ActivatedAbility copyAbility = (ActivatedAbility) ability.copy(); - Effect effect = new DoNothingEffect(); - effect.setValue("key", originaId); - copyAbility.addEffect(effect); + ActivatedAbilityImpl copyAbility = (ActivatedAbilityImpl) ability.copy(); + copyAbility.setMaxActivationsPerTurn(1); perm.addAbility(copyAbility, card.getId(), game); } } @@ -202,135 +186,3 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { return new MairsilThePretenderGainAbilitiesEffect(this); } } - -class MairsilThePretenderWatcher extends Watcher { - - public final Map> activatedThisTurnAbilities = new HashMap<>(); - - public MairsilThePretenderWatcher() { - super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); - } - - public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { - super(watcher); - for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { - activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - Permanent permanent = zEvent.getTarget(); - if (permanent != null) { - this.activatedThisTurnAbilities.remove(permanent.getId()); - } - } - } - if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { - Set permAbilities; - if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { - permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); - } else { - permAbilities = new HashSet<>(); - } - StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); - if (ability != null && ability.getStackAbility().isActivated()) { - for (Effect effect : ability.getAllEffects()) { - if (effect instanceof DoNothingEffect) { - permAbilities.add((UUID) effect.getValue("key")); - this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); - } - } - } - } - } - - @Override - public void reset() { - activatedThisTurnAbilities.clear(); - } - - public Map> getActivatedThisTurnAbilities() { - return this.activatedThisTurnAbilities; - } - - @Override - public MairsilThePretenderWatcher copy() { - return new MairsilThePretenderWatcher(this); - } - -} - -class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { - - public MairsilThePretenderRuleModifyingEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - } - - public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { - super(effect); - } - - @Override - public MairsilThePretenderRuleModifyingEffect copy() { - return new MairsilThePretenderRuleModifyingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); - MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); - if (watcher != null && ability != null && ability.isPresent()) { - for (Effect effect : ability.get().getAllEffects()) { - if (effect instanceof DoNothingEffect) { - UUID originalID = (UUID) effect.getValue("key"); - if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { - if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { - return true; - } - } - } - } - } - return false; - } - - @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - return "This ability can only be activated once each turn."; - } -} - -class DoNothingEffect extends OneShotEffect { - - DoNothingEffect() { - super(Outcome.Neutral); - } - - DoNothingEffect(final DoNothingEffect effect) { - super(effect); - } - - @Override - public DoNothingEffect copy() { - return new DoNothingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MindHarness.java b/Mage.Sets/src/mage/cards/m/MindHarness.java new file mode 100644 index 00000000000..a0ef54b12ab --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MindHarness.java @@ -0,0 +1,89 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.ObjectColor; +import mage.constants.SubType; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.ControlEnchantedEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author TheElk801 + */ +public class MindHarness extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red or green creature"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN))); + } + + public MindHarness(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant red or green creature + TargetPermanent auraTarget = new TargetPermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // You control enchanted creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + } + + public MindHarness(final MindHarness card) { + super(card); + } + + @Override + public MindHarness copy() { + return new MindHarness(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java b/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java index 5b84f8caa4e..b03c18ee684 100644 --- a/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java +++ b/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java @@ -30,17 +30,13 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.TopLibraryCardTypeCondition; -import mage.abilities.costs.Cost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.AddManaOfAnyColorEffect; -import mage.abilities.effects.common.ManaEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.PlayWithTheTopCardRevealedEffect; -import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +44,6 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; -import mage.game.Game; /** * @@ -59,7 +54,7 @@ public class MulDayaChannelers extends CardImpl { private static final String rule1 = "As long as the top card of your library is a creature card, {this} gets +3/+3"; public MulDayaChannelers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.DRUID); this.subtype.add(SubType.SHAMAN); @@ -81,7 +76,7 @@ public class MulDayaChannelers extends CardImpl { new TopLibraryCardTypeCondition(CardType.LAND), "As long as the top card of your library is a land card, Mul Daya Channelers has \"{T}: Add two mana of any one color to your mana pool.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + } public MulDayaChannelers(final MulDayaChannelers card) { @@ -93,46 +88,3 @@ public class MulDayaChannelers extends CardImpl { return new MulDayaChannelers(this); } } - - -class MulDayaChannelersActivateIfConditionManaAbility extends ActivatedManaAbilityImpl { - - private Condition condition; - - public MulDayaChannelersActivateIfConditionManaAbility(Zone zone, ManaEffect effect, Cost cost, Condition condition) { - super(zone, effect, cost); - this.condition = condition; - } - - public MulDayaChannelersActivateIfConditionManaAbility(MulDayaChannelersActivateIfConditionManaAbility ability) { - super(ability); - this.condition = ability.condition; - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (condition.apply(game, this)) { - return super.canActivate(playerId, game); - } - return false; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { - return super.activate(game, noMana); - } - return false; - } - - @Override - public String getRule() { - return "As long as the top card of your library is a land card, {this} has \"{T}: Add two mana of any one color to your mana pool."; - } - - @Override - public MulDayaChannelersActivateIfConditionManaAbility copy() { - return new MulDayaChannelersActivateIfConditionManaAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/p/PerilousVoyage.java b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java new file mode 100644 index 00000000000..a20473e1ada --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java @@ -0,0 +1,105 @@ +/* + * 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.p; + +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.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class PerilousVoyage extends CardImpl { + + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent you don't control"); + + static { + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public PerilousVoyage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2. + this.getSpellAbility().addEffect(new PerilousVoyageEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public PerilousVoyage(final PerilousVoyage card) { + super(card); + } + + @Override + public PerilousVoyage copy() { + return new PerilousVoyage(this); + } +} + +class PerilousVoyageEffect extends OneShotEffect { + + PerilousVoyageEffect() { + super(Outcome.Benefit); + this.staticText = "Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2"; + } + + PerilousVoyageEffect(final PerilousVoyageEffect effect) { + super(effect); + } + + @Override + public PerilousVoyageEffect copy() { + return new PerilousVoyageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + boolean isLittle = permanent.getConvertedManaCost() < 3; + permanent.moveToZone(Zone.HAND, source.getSourceId(), game, true); + if (isLittle && player != null) { + player.scry(2, source, game); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java index 5c5cefc1f9e..293843fd05d 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java @@ -37,6 +37,8 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; @@ -89,14 +91,14 @@ public class QuicksilverElemental extends CardImpl { } } -class QuicksilverElementalEffect extends ContinuousEffectImpl { +class QuicksilverElementalEffect extends OneShotEffect { - public QuicksilverElementalEffect() { - super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + QuicksilverElementalEffect() { + super(Outcome.Benefit); staticText = "{this} gains all activated abilities of target creature until end of turn"; } - public QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { + QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { super(effect); } @@ -112,13 +114,46 @@ class QuicksilverElementalEffect extends ContinuousEffectImpl { if (permanent != null && creature != null) { for (ActivatedAbility ability : creature.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { - permanent.addAbility(ability, source.getSourceId(), game); + Ability newAbility = ability.copy(); + newAbility.newOriginalId(); + game.addEffect(new GainAbilitySourceEffect(newAbility, Duration.EndOfTurn), source); } + return true; } return false; } } +//class QuicksilverElementalEffect extends ContinuousEffectImpl { +// +// public QuicksilverElementalEffect() { +// super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); +// staticText = "{this} gains all activated abilities of target creature until end of turn"; +// } +// +// public QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { +// super(effect); +// } +// +// @Override +// public QuicksilverElementalEffect copy() { +// return new QuicksilverElementalEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// Permanent permanent = game.getPermanent(source.getSourceId()); +// Permanent creature = game.getPermanent(source.getTargets().getFirstTarget()); +// +// if (permanent != null && creature != null) { +// for (ActivatedAbility ability : creature.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { +// permanent.addAbility(ability, source.getSourceId(), game); +// } +// } +// return false; +// } +//} + class QuickSilverElementalBlueManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { public QuickSilverElementalBlueManaEffect() { diff --git a/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java b/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java new file mode 100644 index 00000000000..315b5a02c3a --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java @@ -0,0 +1,75 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class RepeatingBarrage extends CardImpl { + + public RepeatingBarrage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); + + // Repeating Barrage deals 3 damage to target creature or player. + this.getSpellAbility().addEffect(new DamageTargetEffect(3)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + + // Raid — {3}{R}{R}: Return Repeating Barrage from your graveyard to your hand. Activate this ability only if you attacked with a creature this turn. + Ability ability = new ConditionalActivatedAbility(Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToHandEffect(), + new ManaCostsImpl("{3}{R}{R}"), + RaidCondition.instance); + ability.setAbilityWord(AbilityWord.RAID); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public RepeatingBarrage(final RepeatingBarrage card) { + super(card); + } + + @Override + public RepeatingBarrage copy() { + return new RepeatingBarrage(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java b/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java new file mode 100644 index 00000000000..09c803e2250 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java @@ -0,0 +1,189 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.SourceOnBattlefieldCondition; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.Effects; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.ForestwalkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetArtifactPermanent; +import mage.util.CardUtil; + +/** + * + * @author L_J + */ +public class ScarwoodBandits extends CardImpl { + + public ScarwoodBandits(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Forestwalk + this.addAbility(new ForestwalkAbility()); + + // {2}{G}, {tap}: Unless an opponent pays {2}, gain control of target artifact for as long as Scarwood Bandits remains on the battlefield. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DoUnlessAnyOpponentPaysEffect( + new ConditionalContinuousEffect( + new GainControlTargetEffect(Duration.Custom, true), + SourceOnBattlefieldCondition.instance, + "gain control of target artifact for as long as {this} remains on the battlefield"), + new GenericManaCost(2)), + new ManaCostsImpl("{2}{G}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetArtifactPermanent()); + this.addAbility(ability); + } + + public ScarwoodBandits(final ScarwoodBandits card) { + super(card); + } + + @Override + public ScarwoodBandits copy() { + return new ScarwoodBandits(this); + } +} + +class DoUnlessAnyOpponentPaysEffect extends OneShotEffect { + + protected Effects executingEffects = new Effects(); + private final Cost cost; + private String chooseUseText; + + public DoUnlessAnyOpponentPaysEffect(Effect effect, Cost cost) { + this(effect, cost, null); + } + + public DoUnlessAnyOpponentPaysEffect(Effect effect, Cost cost, String chooseUseText) { + super(Outcome.Benefit); + this.executingEffects.add(effect); + this.cost = cost; + this.chooseUseText = chooseUseText; + } + + public DoUnlessAnyOpponentPaysEffect(final DoUnlessAnyOpponentPaysEffect effect) { + super(effect); + this.executingEffects = effect.executingEffects.copy(); + this.cost = effect.cost.copy(); + this.chooseUseText = effect.chooseUseText; + } + + public void addEffect(Effect effect) { + executingEffects.add(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + String message; + if (chooseUseText == null) { + String effectText = executingEffects.getText(source.getModes().getMode()); + message = "Pay " + cost.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?"; + } else { + message = chooseUseText; + } + message = CardUtil.replaceSourceName(message, sourceObject.getName()); + boolean result = true; + boolean doEffect = true; + // check if any opponent is willing to pay + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null && player != controller && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) { + cost.clearPaid(); + if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { + if (!game.isSimulation()) { + game.informPlayers(player.getLogName() + " pays the cost to prevent the effect"); + } + doEffect = false; + } + } + } + // do the effects if nobody paid + if (doEffect) { + for (Effect effect : executingEffects) { + effect.setTargetPointer(this.targetPointer); + if (effect instanceof OneShotEffect) { + result &= effect.apply(game, source); + } else { + game.addEffect((ContinuousEffect) effect, source); + } + } + } + return result; + } + return false; + } + + protected Player getPayingPlayer(Game game, Ability source) { + return game.getPlayer(source.getControllerId()); + } + + @Override + public String getText(Mode mode) { + if (!staticText.isEmpty()) { + return staticText; + } + String effectsText = executingEffects.getText(mode); + return effectsText.substring(0, effectsText.length() - 1) + " unless any opponent pays " + cost.getText(); + } + + @Override + public DoUnlessAnyOpponentPaysEffect copy() { + return new DoUnlessAnyOpponentPaysEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java b/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java new file mode 100644 index 00000000000..ab340946d07 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreatureExploresTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.CrewAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class ShadowedCaravel extends CardImpl { + + public ShadowedCaravel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever a creature you control explores, put a +1/+1 counter on Shadowed Caravel. + Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); + Ability ability = new CreatureExploresTriggeredAbility(effect); + this.addAbility(ability); + + // Crew 2 + this.addAbility(new CrewAbility(2)); + + } + + public ShadowedCaravel(final ShadowedCaravel card) { + super(card); + } + + @Override + public ShadowedCaravel copy() { + return new ShadowedCaravel(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java new file mode 100644 index 00000000000..6745cc8009a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -0,0 +1,93 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.token.TreasureToken; +import mage.game.stack.StackObject; +import mage.target.TargetSpell; + +/** + * + * @author TheElk801 + */ +public class SpellSwindle extends CardImpl { + + public SpellSwindle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}"); + + // Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. They have "T, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().addEffect(new SpellSwindleEffect()); + } + + public SpellSwindle(final SpellSwindle card) { + super(card); + } + + @Override + public SpellSwindle copy() { + return new SpellSwindle(this); + } +} + +class SpellSwindleEffect extends OneShotEffect { + + public SpellSwindleEffect() { + super(Outcome.Detriment); + staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool"; + } + + public SpellSwindleEffect(final SpellSwindleEffect effect) { + super(effect); + } + + @Override + public SpellSwindleEffect copy() { + return new SpellSwindleEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + StackObject stackObject = game.getStack().getStackObject(targetPointer.getFirst(game, source)); + if (stackObject != null) { + game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); + return new CreateTokenEffect(new TreasureToken(), stackObject.getConvertedManaCost()).apply(game, source); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java new file mode 100644 index 00000000000..927439e4939 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.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.cards.s; + +import java.util.UUID; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class SpiritualAsylum extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("Creatures and lands you control"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND) + )); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public SpiritualAsylum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); + + // Creatures and lands you control have shroud. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(ShroudAbility.getInstance(), + Duration.WhileOnBattlefield, filter))); + + // When a creature you control attacks, sacrifice Spiritual Asylum. + AttacksCreatureYouControlTriggeredAbility ability = new AttacksCreatureYouControlTriggeredAbility(new SacrificeSourceEffect()); + ability.setOnce(true); + this.addAbility(ability); + } + + public SpiritualAsylum(final SpiritualAsylum card) { + super(card); + } + + @Override + public SpiritualAsylum copy() { + return new SpiritualAsylum(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpitfireBastion.java b/Mage.Sets/src/mage/cards/s/SpitfireBastion.java new file mode 100644 index 00000000000..5de16e5abe0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpitfireBastion.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.mana.RedManaAbility; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class SpitfireBastion extends CardImpl { + + public SpitfireBastion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.nightCard = true; + + // {T}: Add {R} to your mana pool. + this.addAbility(new RedManaAbility()); + + // {2}{R}, {T}: Spitfire Bastion deals 3 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new TapSourceCost()); + ability.addCost(new ManaCostsImpl("{2}{R}")); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public SpitfireBastion(final SpitfireBastion card) { + super(card); + } + + @Override + public SpitfireBastion copy() { + return new SpitfireBastion(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java b/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java index 7dd227bed81..75d9e447129 100644 --- a/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java +++ b/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java @@ -72,7 +72,7 @@ class SwordPointDiplomacyEffect extends OneShotEffect { SwordPointDiplomacyEffect() { super(Outcome.Benefit); - this.staticText = ""; + this.staticText = "Reveal the top three cards of your library. For each of those cards, put that card into your hand unless any opponent pays 3 life. Then exile the rest."; } SwordPointDiplomacyEffect(final SwordPointDiplomacyEffect effect) { @@ -102,10 +102,10 @@ class SwordPointDiplomacyEffect extends OneShotEffect { Cost cost = new PayLifeCost(3); for (UUID oppId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(oppId); - if (!(opponent != null + if (opponent != null && cost.canPay(source, source.getSourceId(), opponent.getId(), game) && opponent.chooseUse(Outcome.Neutral, "Pay 3 life to prevent " + controller.getLogName() + " from getting " + card.getLogName() + "?", source, game) - && cost.pay(source, game, source.getSourceId(), opponent.getId(), true))) { + && cost.pay(source, game, source.getSourceId(), opponent.getId(), true)) { keepIt = false; } } diff --git a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java index 1038660daf7..5a4239c0926 100644 --- a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java +++ b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java @@ -25,22 +25,21 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.t; -import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; 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.target.common.TargetCardInLibrary; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; /** * @@ -49,8 +48,14 @@ import java.util.UUID; public class TerramorphicExpanse extends CardImpl { public TerramorphicExpanse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); - this.addAbility(new TerramorphicExpanseAbility()); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); + + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public TerramorphicExpanse(final TerramorphicExpanse card) { @@ -63,24 +68,3 @@ public class TerramorphicExpanse extends CardImpl { } } - -class TerramorphicExpanseAbility extends ActivatedAbilityImpl { - - public TerramorphicExpanseAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new SacrificeSourceCost()); - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - addEffect(new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay)); - } - - public TerramorphicExpanseAbility(final TerramorphicExpanseAbility ability) { - super(ability); - } - - @Override - public TerramorphicExpanseAbility copy() { - return new TerramorphicExpanseAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java index 335871c0318..cf553d55043 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java @@ -37,22 +37,15 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.common.FilterControlledCreaturePermanent; /** * @author nantuko */ public class ThrabenSentry extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature"); - - static { - filter.add(new AnotherPredicate()); - } public ThrabenSentry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -66,7 +59,7 @@ public class ThrabenSentry extends CardImpl { // Whenever another creature you control dies, you may transform Thraben Sentry. this.addAbility(new TransformAbility()); - this.addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(true), true, filter)); + this.addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(true), true, new FilterControlledCreaturePermanent())); } public ThrabenSentry(final ThrabenSentry card) { diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java new file mode 100644 index 00000000000..4247174359f --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -0,0 +1,194 @@ +/* + * 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.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.s.SpitfireBastion; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.common.CastSpellLastTurnWatcher; + +/** + * + * @author TheElk801 + */ +public class VancesBlastingCannons extends CardImpl { + + public VancesBlastingCannons(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.transformable = true; + this.secondSideCardClazz = SpitfireBastion.class; + + // At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new VancesBlastingCannonsExileEffect(), TargetController.YOU, false)); + + // Whenever you cast your third spell in a turn, transform Vance's Blasting Cannons. + this.addAbility(new TransformAbility()); + this.addAbility(new VancesBlastingCannonsFlipTrigger(), new CastSpellLastTurnWatcher()); + } + + public VancesBlastingCannons(final VancesBlastingCannons card) { + super(card); + } + + @Override + public VancesBlastingCannons copy() { + return new VancesBlastingCannons(this); + } +} + +class VancesBlastingCannonsExileEffect extends OneShotEffect { + + public VancesBlastingCannonsExileEffect() { + super(Outcome.Benefit); + this.staticText = "exile the top card of your library. If it's a nonland card, you may cast that card this turn"; + } + + public VancesBlastingCannonsExileEffect(final VancesBlastingCannonsExileEffect effect) { + super(effect); + } + + @Override + public VancesBlastingCannonsExileEffect copy() { + return new VancesBlastingCannonsExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && sourcePermanent != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + String exileName = sourcePermanent.getIdName() + (card.isLand() ? "" : "