diff --git a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java new file mode 100644 index 00000000000..9085a70b0ec --- /dev/null +++ b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java @@ -0,0 +1,199 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.fifthedition; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfDrawTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.watchers.WatcherImpl; + +/** + * + * @author LevelX2 + */ +public class SylvanLibrary extends CardImpl { + + public SylvanLibrary(UUID ownerId) { + super(ownerId, 191, "Sylvan Library", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + this.expansionSetCode = "5ED"; + + this.color.setGreen(true); + + // At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. + this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true)); + + this.addWatcher(new CardsDrawnThisTurnWatcher()); + + } + + public SylvanLibrary(final SylvanLibrary card) { + super(card); + } + + @Override + public SylvanLibrary copy() { + return new SylvanLibrary(this); + } +} + +class SylvanLibraryEffect extends OneShotEffect { + + public SylvanLibraryEffect() { + super(Outcome.DrawCard); + this.staticText = "draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library"; + } + + public SylvanLibraryEffect(final SylvanLibraryEffect effect) { + super(effect); + } + + @Override + public SylvanLibraryEffect copy() { + return new SylvanLibraryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.drawCards(2, game); + CardsDrawnThisTurnWatcher watcher = (CardsDrawnThisTurnWatcher) game.getState().getWatchers().get("CardsDrawnThisTurnWatcher", source.getControllerId()); + if (watcher != null) { + Cards cards = new CardsImpl(); + for (UUID cardId : controller.getHand()) { + if (watcher.getCardsDrawnThisTurn().contains(cardId)) { + Card card = game.getCard(cardId); + if (card != null) { + cards.add(card); + } + } + } + int numberOfTargets = Math.min(2, cards.size()); + if (numberOfTargets > 0) { + TargetCard target = new TargetCard(numberOfTargets, Zone.PICK, new FilterCard(new StringBuilder(numberOfTargets).append(" cards of cards drawn this turn").toString())); + target.setRequired(true); + controller.chooseTarget(outcome, cards, target, source, game); + + Cards cardsPutBack = new CardsImpl(); + for (UUID cardId :(List) target.getTargets()) { + Card card = cards.get(cardId, game); + if (card != null) { + if (controller.canPayLifeCost() + && controller.getLife() >= 4 + && controller.chooseUse(outcome, new StringBuilder("Pay 4 life for ").append(card.getName()).append("? (Otherwise it's put on top of your library)").toString(), game)) { + controller.loseLife(4, game); + game.informPlayers(new StringBuilder(controller.getName()).append(" pays 4 life to keep a card on hand").toString()); + } else { + cardsPutBack.add(card); + } + } + } + int numberOfCardsToPutBack = cardsPutBack.size(); + if (numberOfCardsToPutBack > 1) { + TargetCard target2 = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of your library (last chosen will be on top)")); + target2.setRequired(true); + while (cardsPutBack.size() > 1) { + controller.choose(Outcome.Benefit, cardsPutBack, target2, game); + Card card = cardsPutBack.get(target2.getFirstTarget(), game); + if (card != null) { + cardsPutBack.remove(card); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + } + target2.clearChosen(); + } + } + if (cardsPutBack.size() == 1) { + Card card = cardsPutBack.get(cardsPutBack.iterator().next(), game); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + } + if (numberOfCardsToPutBack > 0) { + game.informPlayers(new StringBuilder(controller.getName()).append(" puts ").append(numberOfCardsToPutBack).append(" card(s) back to library").toString()); + } + } + } + return true; + } + return false; + } +} + +class CardsDrawnThisTurnWatcher extends WatcherImpl { + + private final Set cardsDrawnThisTurn = new HashSet(); + + + public CardsDrawnThisTurnWatcher() { + super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER); + } + + public CardsDrawnThisTurnWatcher(final CardsDrawnThisTurnWatcher watcher) { + super(watcher); + this.cardsDrawnThisTurn.addAll(watcher.cardsDrawnThisTurn); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DREW_CARD && event.getPlayerId().equals(this.getControllerId())) { + cardsDrawnThisTurn.add(event.getTargetId()); + } + } + + public Set getCardsDrawnThisTurn() { + return cardsDrawnThisTurn; + } + + @Override + public void reset() { + super.reset(); + cardsDrawnThisTurn.clear(); + } + + @Override + public CardsDrawnThisTurnWatcher copy() { + return new CardsDrawnThisTurnWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/SylvanLibrary.java b/Mage.Sets/src/mage/sets/fourthedition/SylvanLibrary.java new file mode 100644 index 00000000000..07836a3b582 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/SylvanLibrary.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class SylvanLibrary extends mage.sets.fifthedition.SylvanLibrary { + + public SylvanLibrary(UUID ownerId) { + super(ownerId); + this.cardNumber = 157; + this.expansionSetCode = "4ED"; + } + + public SylvanLibrary(final SylvanLibrary card) { + super(card); + } + + @Override + public SylvanLibrary copy() { + return new SylvanLibrary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/TsabosWeb.java b/Mage.Sets/src/mage/sets/invasion/TsabosWeb.java new file mode 100644 index 00000000000..e97ff0c931f --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/TsabosWeb.java @@ -0,0 +1,120 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.PlayLandAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.mana.ManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class TsabosWeb extends CardImpl { + + public TsabosWeb(UUID ownerId) { + super(ownerId, 317, "Tsabo's Web", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "INV"; + + // When Tsabo's Web enters the battlefield, draw a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardControllerEffect(1), false)); + // Each land with an activated ability that isn't a mana ability doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TsabosWebPreventUntapEffect())); + + } + + public TsabosWeb(final TsabosWeb card) { + super(card); + } + + @Override + public TsabosWeb copy() { + return new TsabosWeb(this); + } +} + +class TsabosWebPreventUntapEffect extends ReplacementEffectImpl { + + public TsabosWebPreventUntapEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Each land with an activated ability that isn't a mana ability doesn't untap during its controller's untap step"; + } + + public TsabosWebPreventUntapEffect(final TsabosWebPreventUntapEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public TsabosWebPreventUntapEffect copy() { + return new TsabosWebPreventUntapEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.getCardType().contains(CardType.LAND)) { + for (Ability ability :permanent.getAbilities()) { + if (!(ability instanceof PlayLandAbility) + && !(ability instanceof ManaAbility) + && ability instanceof ActivatedAbility) { + return true; + } + } + } + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/judgment/SylvanSafekeeper.java b/Mage.Sets/src/mage/sets/judgment/SylvanSafekeeper.java new file mode 100644 index 00000000000..03561ba754e --- /dev/null +++ b/Mage.Sets/src/mage/sets/judgment/SylvanSafekeeper.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.judgment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledLandPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author LevelX2 + */ +public class SylvanSafekeeper extends CardImpl { + + public SylvanSafekeeper(UUID ownerId) { + super(ownerId, 133, "Sylvan Safekeeper", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "JUD"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + + this.color.setGreen(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Sacrifice a land: Target creature you control gains shroud until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new GainAbilityTargetEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), + new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addTarget(new TargetControlledCreaturePermanent(true)); + this.addAbility(ability); + } + + public SylvanSafekeeper(final SylvanSafekeeper card) { + super(card); + } + + @Override + public SylvanSafekeeper copy() { + return new SylvanSafekeeper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/legends/SylvanLibrary.java b/Mage.Sets/src/mage/sets/legends/SylvanLibrary.java new file mode 100644 index 00000000000..8e79c0c99bf --- /dev/null +++ b/Mage.Sets/src/mage/sets/legends/SylvanLibrary.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.legends; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class SylvanLibrary extends mage.sets.fifthedition.SylvanLibrary { + + public SylvanLibrary(UUID ownerId) { + super(ownerId); + this.cardNumber = 121; + this.expansionSetCode = "LEG"; + this.rarity = Rarity.UNCOMMON; + } + + public SylvanLibrary(final SylvanLibrary card) { + super(card); + } + + @Override + public SylvanLibrary copy() { + return new SylvanLibrary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/weatherlight/NullRod.java b/Mage.Sets/src/mage/sets/weatherlight/NullRod.java new file mode 100644 index 00000000000..b7723900750 --- /dev/null +++ b/Mage.Sets/src/mage/sets/weatherlight/NullRod.java @@ -0,0 +1,104 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.weatherlight; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class NullRod extends CardImpl { + + public NullRod(UUID ownerId) { + super(ownerId, 154, "Null Rod", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "WTH"; + + // Activated abilities of artifacts can't be activated. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantActivateAbilitiesEffect())); + } + + public NullRod(final NullRod card) { + super(card); + } + + @Override + public NullRod copy() { + return new NullRod(this); + } +} + +class CantActivateAbilitiesEffect extends ReplacementEffectImpl { + + public CantActivateAbilitiesEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Activated abilities of artifacts can't be activated."; + } + + public CantActivateAbilitiesEffect(final CantActivateAbilitiesEffect effect) { + super(effect); + } + + @Override + public CantActivateAbilitiesEffect copy() { + return new CantActivateAbilitiesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent.getCardType().contains(CardType.ARTIFACT)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/weatherlight/Peacekeeper.java b/Mage.Sets/src/mage/sets/weatherlight/Peacekeeper.java new file mode 100644 index 00000000000..433faade07e --- /dev/null +++ b/Mage.Sets/src/mage/sets/weatherlight/Peacekeeper.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.weatherlight; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +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; + +/** + * + * @author LevelX2 + */ +public class Peacekeeper extends CardImpl { + + public Peacekeeper(UUID ownerId) { + super(ownerId, 138, "Peacekeeper", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "WTH"; + this.subtype.add("Human"); + + this.color.setWhite(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, sacrifice Peacekeeper unless you pay {1}{W}. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{1}{W}")), TargetController.YOU, false)); + + // Creatures can't attack. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PeacekeeperCantAttackEffect())); + } + + public Peacekeeper(final Peacekeeper card) { + super(card); + } + + @Override + public Peacekeeper copy() { + return new Peacekeeper(this); + } +} + +class PeacekeeperCantAttackEffect extends ReplacementEffectImpl { + + private static final String effectText = "Creatures can't attack"; + + PeacekeeperCantAttackEffect ( ) { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = effectText; + } + + PeacekeeperCantAttackEffect (final PeacekeeperCantAttackEffect effect ) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player atackingPlayer = game.getPlayer(event.getPlayerId()); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent != null && atackingPlayer != null) { + game.informPlayer(atackingPlayer, new StringBuilder(sourcePermanent.getName()).append(" prevents you from attacking with this creature.").toString()); + } + + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getType() == GameEvent.EventType.DECLARE_ATTACKER; + } + + @Override + public PeacekeeperCantAttackEffect copy() { + return new PeacekeeperCantAttackEffect(this); + } + +} diff --git a/Mage/src/mage/abilities/Ability.java b/Mage/src/mage/abilities/Ability.java index 3d34746b6d9..af119eacf84 100644 --- a/Mage/src/mage/abilities/Ability.java +++ b/Mage/src/mage/abilities/Ability.java @@ -62,6 +62,7 @@ public interface Ability extends Controllable, Serializable { * @return A {@link java.util.UUID} which the game will use to store and retrieve * the exact instance of this ability. */ + @Override UUID getId(); /** diff --git a/Mage/src/mage/abilities/effects/common/ScryEffect.java b/Mage/src/mage/abilities/effects/common/ScryEffect.java index f2c1d9debac..7c47aba0f81 100644 --- a/Mage/src/mage/abilities/effects/common/ScryEffect.java +++ b/Mage/src/mage/abilities/effects/common/ScryEffect.java @@ -100,14 +100,14 @@ public class ScryEffect extends OneShotEffect { Card card = cards.get(target2.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); } target2.clearChosen(); } } if (cards.size() == 1) { Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); } game.informPlayers(new StringBuilder(player.getName()).append(" puts ") .append(onBottom).append(onBottom == 1 ?" card":" cards") diff --git a/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java b/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java index c8b6e29ad37..de0c28b5a09 100644 --- a/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java +++ b/Mage/src/mage/watchers/common/CardsPutIntoGraveyardWatcher.java @@ -34,7 +34,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; - import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; @@ -42,8 +41,6 @@ import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.watchers.WatcherImpl; - - /** * Counts amount of cards put into graveyards of players during the current turn. * Also the UUIDs of cards that went to graveyard from Battlefield this turn. @@ -52,8 +49,8 @@ import mage.watchers.WatcherImpl; */ public class CardsPutIntoGraveyardWatcher extends WatcherImpl { - private Map amountOfCardsThisTurn = new HashMap(); - private Set cardsPutToGraveyardFromBattlefield = new HashSet(); + private final Map amountOfCardsThisTurn = new HashMap(); + private final Set cardsPutToGraveyardFromBattlefield = new HashSet(); public CardsPutIntoGraveyardWatcher() { @@ -65,6 +62,7 @@ public class CardsPutIntoGraveyardWatcher extends WatcherImpl entry : watcher.amountOfCardsThisTurn.entrySet()) { amountOfCardsThisTurn.put(entry.getKey(), entry.getValue()); } + this.cardsPutToGraveyardFromBattlefield.addAll(watcher.cardsPutToGraveyardFromBattlefield); } @Override