diff --git a/Mage.Sets/src/mage/sets/alliances/ElvishSpiritGuide.java b/Mage.Sets/src/mage/sets/alliances/ElvishSpiritGuide.java new file mode 100644 index 00000000000..dc8a26d5dbf --- /dev/null +++ b/Mage.Sets/src/mage/sets/alliances/ElvishSpiritGuide.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.sets.alliances; + +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.costs.CostImpl; +import mage.abilities.effects.common.BasicManaEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author Plopman + */ +public class ElvishSpiritGuide extends CardImpl { + + public ElvishSpiritGuide(UUID ownerId) { + super(ownerId, 69, "Elvish Spirit Guide", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "ALL"; + this.subtype.add("Elf"); + this.subtype.add("Spirit"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Exile Elvish Spirit Guide from your hand: Add {G} to your mana pool. + this.addAbility(new SimpleManaAbility(Constants.Zone.HAND, new BasicManaEffect(Mana.GreenMana), new ExileSourceFromHandCost())); + } + + public ElvishSpiritGuide(final ElvishSpiritGuide card) { + super(card); + } + + @Override + public ElvishSpiritGuide copy() { + return new ElvishSpiritGuide(this); + } +} + + +class ExileSourceFromHandCost extends CostImpl { + + public ExileSourceFromHandCost() { + this.text = "Exile {this} from your hand"; + } + + public ExileSourceFromHandCost(ExileSourceFromHandCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Card card = game.getCard(sourceId); + Player player = game.getPlayer(controllerId); + if (player != null && player.getHand().contains(sourceId) && card != null) { + paid = card.moveToExile(ability.getSourceId(), "from Hand", ability.getSourceId(), game); + } + return paid; + } + + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + Player player = game.getPlayer(controllerId); + if (player != null && player.getHand().contains(sourceId)) { + return true; + } + return false; + } + + @Override + public ExileSourceFromHandCost copy() { + return new ExileSourceFromHandCost(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/coldsnap/RiteOfFlame.java b/Mage.Sets/src/mage/sets/coldsnap/RiteOfFlame.java new file mode 100644 index 00000000000..d1863bf10a3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/coldsnap/RiteOfFlame.java @@ -0,0 +1,103 @@ +/* + * 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.coldsnap; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.effects.common.ManaEffect; +import mage.cards.CardImpl; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author Plopman + */ +public class RiteOfFlame extends CardImpl { + + public RiteOfFlame(UUID ownerId) { + super(ownerId, 96, "Rite of Flame", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{R}"); + this.expansionSetCode = "CSP"; + + this.color.setRed(true); + + // Add {R}{R} to your mana pool, then add {R} to your mana pool for each card named Rite of Flame in each graveyard. + this.getSpellAbility().addEffect(new RiteOfFlameManaEffect()); + } + + public RiteOfFlame(final RiteOfFlame card) { + super(card); + } + + @Override + public RiteOfFlame copy() { + return new RiteOfFlame(this); + } +} + +class RiteOfFlameManaEffect extends ManaEffect { + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(new NamePredicate("Rite of Flame")); + } + + RiteOfFlameManaEffect() { + super(); + staticText = "Add {R}{R} to your mana pool, then add {R} to your mana pool for each card named Rite of Flame in each graveyard"; + } + + RiteOfFlameManaEffect(final RiteOfFlameManaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if(controller != null){ + int count = 0; + for(Player player : game.getPlayers().values()){ + if(player != null){ + count += player.getGraveyard().count(filter, game); + } + } + controller.getManaPool().addMana(Mana.RedMana(count + 2), game, source); + } + return false; + } + + @Override + public RiteOfFlameManaEffect copy() { + return new RiteOfFlameManaEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/futuresight/StreetWraith.java b/Mage.Sets/src/mage/sets/futuresight/StreetWraith.java new file mode 100644 index 00000000000..f313120a7e4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/futuresight/StreetWraith.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.futuresight; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.keyword.SwampwalkAbility; +import mage.cards.CardImpl; + +/** + * + * @author Plopman + */ +public class StreetWraith extends CardImpl { + + public StreetWraith(UUID ownerId) { + super(ownerId, 90, "Street Wraith", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "FUT"; + this.subtype.add("Wraith"); + + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Swampwalk + this.addAbility(new SwampwalkAbility()); + // Cycling-Pay 2 life. + this.addAbility(new CyclingAbility(new PayLifeCost(2))); + } + + public StreetWraith(final StreetWraith card) { + super(card); + } + + @Override + public StreetWraith copy() { + return new StreetWraith(this); + } +} diff --git a/Mage.Sets/src/mage/sets/iceage/TinderWall.java b/Mage.Sets/src/mage/sets/iceage/TinderWall.java new file mode 100644 index 00000000000..dabb81e0f8c --- /dev/null +++ b/Mage.Sets/src/mage/sets/iceage/TinderWall.java @@ -0,0 +1,159 @@ +/* + * 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.iceage; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.BasicManaEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.WatcherImpl; + +/** + * + * @author Plopman + */ +public class TinderWall extends CardImpl { + + public TinderWall(UUID ownerId) { + super(ownerId, 158, "Tinder Wall", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "ICE"; + this.subtype.add("Plant"); + this.subtype.add("Wall"); + + this.color.setGreen(true); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + // Sacrifice Tinder Wall: Add {R}{R} to your mana pool. + this.addAbility(new SimpleManaAbility(Constants.Zone.BATTLEFIELD, new BasicManaEffect(Mana.RedMana(2)), new SacrificeSourceCost())); + // {R}, Sacrifice Tinder Wall: Tinder Wall deals 2 damage to target creature it's blocking. + FilterAttackingCreature filter = new FilterAttackingCreature("creature it's blocking"); + filter.add(new BlockingByPredicate(this.getId())); + Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl("{R}")); + ability.addTarget(new TargetCreaturePermanent(filter)); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + + + this.addWatcher(new BlockedByWatcher()); + } + + public TinderWall(final TinderWall card) { + super(card); + } + + @Override + public TinderWall copy() { + return new TinderWall(this); + } +} + + +class BlockedByWatcher extends WatcherImpl { + + public List blockedByWatcher = new ArrayList(); + + public BlockedByWatcher() { + super("BlockedByWatcher", Constants.WatcherScope.CARD); + } + + public BlockedByWatcher(final BlockedByWatcher watcher) { + super(watcher); + this.blockedByWatcher = watcher.blockedByWatcher; + } + + @Override + public BlockedByWatcher copy() { + return new BlockedByWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + if (sourceId.equals(event.getSourceId()) && !blockedByWatcher.contains(event.getTargetId())) { + blockedByWatcher.add(event.getTargetId()); + } + } + } + + @Override + public void reset() { + super.reset(); + blockedByWatcher.clear(); + } + +} + +class BlockingByPredicate implements Predicate { + + private UUID source; + + public BlockingByPredicate(UUID source) { + this.source = source; + } + + @Override + public boolean apply(Permanent input, Game game) { + BlockedByWatcher watcher = (BlockedByWatcher) game.getState().getWatchers().get("BlockedByWatcher", source); + + for(UUID uuid :watcher.blockedByWatcher){ + Permanent creature = game.getPermanent(uuid); + if(creature != null && creature.getId().equals(input.getId())){ + return true; + } + } + return false; + + } + + @Override + public String toString() { + return "creature it's blocking"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/LandGrant.java b/Mage.Sets/src/mage/sets/mercadianmasques/LandGrant.java new file mode 100644 index 00000000000..dde23f10692 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mercadianmasques/LandGrant.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.sets.mercadianmasques; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.abilities.Ability; +import mage.abilities.costs.AlternativeCostImpl; +import mage.abilities.costs.CompositeCost; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author Plopman + */ +public class LandGrant extends CardImpl { + + private static final FilterLandCard filter = new FilterLandCard("Forest card"); + public LandGrant(UUID ownerId) { + super(ownerId, 255, "Land Grant", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{G}"); + this.expansionSetCode = "MMQ"; + + this.color.setGreen(true); + + // If you have no land cards in hand, you may reveal your hand rather than pay Land Grant's mana cost. + Cost cost = new CompositeCost(new GenericManaCost(0), new LandGrantCost(), "If you have no land cards in hand, you may reveal your hand"); + this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl("If you have no land cards in hand, you may reveal your hand rather than pay Land Grant's mana cost", cost)); + // Search your library for a Forest card, reveal that card, and put it into your hand. Then shuffle your library. + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true)); + } + + public LandGrant(final LandGrant card) { + super(card); + } + + @Override + public LandGrant copy() { + return new LandGrant(this); + } +} + +class LandGrantCost extends CostImpl { + + public LandGrantCost() { + this.text = "If you have no land cards in hand, you may reveal your hand"; + } + + public LandGrantCost(LandGrantCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Player player = game.getPlayer(controllerId); + if (player != null) { + player.revealCards("Land Grant", player.getHand(), game); + paid = true; + } + return paid; + } + + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + Player player = game.getPlayer(controllerId); + if (player != null && player.getHand().count(new FilterLandCard(), game) == 0) { + return true; + } + return false; + } + + @Override + public LandGrantCost copy() { + return new LandGrantCost(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/mirrodin/ChromeMox.java b/Mage.Sets/src/mage/sets/mirrodin/ChromeMox.java new file mode 100644 index 00000000000..e7beac7996e --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/ChromeMox.java @@ -0,0 +1,202 @@ +/* + * 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.mirrodin; + +import java.awt.Color; +import java.util.List; +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.AbilityImpl; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ManaEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.abilities.mana.ManaAbility; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; + +/** + * + * @author Plopman + */ +public class ChromeMox extends CardImpl { + + public ChromeMox(UUID ownerId) { + super(ownerId, 152, "Chrome Mox", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{0}"); + this.expansionSetCode = "MRD"; + + // Imprint - When Chrome Mox enters the battlefield, you may exile a nonartifact, nonland card from your hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ChromeMoxEffect(), true)); + // {tap}: Add one mana of any of the exiled card's colors to your mana pool. + this.addAbility(new SimpleManaAbility(Constants.Zone.BATTLEFIELD, new ChromeMoxManaEffect(), new TapSourceCost())); + } + + public ChromeMox(final ChromeMox card) { + super(card); + } + + @Override + public ChromeMox copy() { + return new ChromeMox(this); + } +} + +class ChromeMoxEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("nonartifact, nonland card"); + static { + filter.add(Predicates.not(Predicates.or(new CardTypePredicate(CardType.LAND), new CardTypePredicate(CardType.ARTIFACT)))); + } + public ChromeMoxEffect() { + super(Constants.Outcome.Benefit); + staticText = "exile a nonartifact, nonland card from your hand"; + } + + public ChromeMoxEffect(ChromeMoxEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player.getHand().size() > 0) { + TargetCard target = new TargetCard(Constants.Zone.HAND, filter); + player.choose(Constants.Outcome.Benefit, player.getHand(), target, game); + Card card = player.getHand().get(target.getFirstTarget(), game); + if (card != null) { + card.moveToExile(getId(), "Chrome Mox (Imprint)", source.getSourceId(), game); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + permanent.imprint(card.getId(), game); + } + return true; + } + } + return true; + } + + @Override + public ChromeMoxEffect copy() { + return new ChromeMoxEffect(this); + } + + +} + +class ChromeMoxManaEffect extends ManaEffect { + + + ChromeMoxManaEffect() { + super(); + staticText = "Add one mana of any of the exiled card's colors to your mana pool"; + } + + ChromeMoxManaEffect(ChromeMoxManaEffect effect) { + super(effect); + } + + + + @Override + public ChromeMoxManaEffect copy() { + return new ChromeMoxManaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + if (permanent != null && player != null) { + List imprinted = permanent.getImprinted(); + if (imprinted.size() > 0) { + Card imprintedCard = game.getCard(imprinted.get(0)); + if (imprintedCard != null) { + Choice choice = new ChoiceImpl(true); + choice.setMessage("Pick a mana color"); + ObjectColor color = imprintedCard.getColor(); + if (color.isBlack()) { + choice.getChoices().add("Black"); + } + if (color.isRed()) { + choice.getChoices().add("Red"); + } + if (color.isBlue()) { + choice.getChoices().add("Blue"); + } + if (color.isGreen()) { + choice.getChoices().add("Green"); + } + if (color.isWhite()) { + choice.getChoices().add("White"); + } + + if (choice.getChoices().size() > 0) { + if (choice.getChoices().size() == 1) { + choice.setChoice(choice.getChoices().iterator().next()); + } else { + player.choose(outcome, choice, game); + } + if (choice.getChoice().equals("Black")) { + player.getManaPool().addMana(Mana.BlackMana, game, source); + } else if (choice.getChoice().equals("Blue")) { + player.getManaPool().addMana(Mana.BlueMana, game, source); + } else if (choice.getChoice().equals("Red")) { + player.getManaPool().addMana(Mana.RedMana, game, source); + } else if (choice.getChoice().equals("Green")) { + player.getManaPool().addMana(Mana.GreenMana, game, source); + } else if (choice.getChoice().equals("White")) { + player.getManaPool().addMana(Mana.WhiteMana, game, source); + } else if (choice.getChoice().equals("Colorless")) { + player.getManaPool().addMana(Mana.ColorlessMana, game, source); + } + } + } + + } + } + return true; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java b/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java new file mode 100644 index 00000000000..43cda00b81c --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java @@ -0,0 +1,150 @@ +/* + * 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.mirrodin; + +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +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.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author Plopman + */ +public class GoblinCharbelcher extends CardImpl { + + public GoblinCharbelcher(UUID ownerId) { + super(ownerId, 176, "Goblin Charbelcher", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}"); + this.expansionSetCode = "MRD"; + + // {3}, {tap}: Reveal cards from the top of your library until you reveal a land card. Goblin Charbelcher deals damage equal to the number of nonland cards revealed this way to target creature or player. If the revealed land card was a Mountain, Goblin Charbelcher deals double that damage instead. Put the revealed cards on the bottom of your library in any order. + Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new GoblinCharbelcherEffect(), new ManaCostsImpl("{3}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public GoblinCharbelcher(final GoblinCharbelcher card) { + super(card); + } + + @Override + public GoblinCharbelcher copy() { + return new GoblinCharbelcher(this); + } +} + +class GoblinCharbelcherEffect extends OneShotEffect { + + public GoblinCharbelcherEffect() { + super(Outcome.Damage); + this.staticText = "Reveal cards from the top of your library until you reveal a land card. {this} deals damage equal to the number of nonland cards revealed this way to target creature or player. If the revealed land card was a Mountain, {this} deals double that damage instead. Put the revealed cards on the bottom of your library in any order"; + } + + public GoblinCharbelcherEffect(final GoblinCharbelcherEffect effect) { + super(effect); + } + + @Override + public GoblinCharbelcherEffect copy() { + return new GoblinCharbelcherEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + boolean isMountain = false; + Card sourceCard = game.getCard(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + + if (player == null || sourceCard == null) { + return false; + } + Cards cards = new CardsImpl(Constants.Zone.PICK); + while (player.getLibrary().size() > 0) { + Card card = player.getLibrary().removeFromTop(game); + if (card != null) { + cards.add(card); + if(card.getCardType().contains(CardType.LAND)){ + if(card.getSubtype().contains("Mountain")){ + isMountain = true; + } + break; + } + } + else{ + break; + } + } + player.revealCards(sourceCard.getName(), cards, game); + int damage = cards.size(); + if(isMountain == true){ + damage *= 2; + } + + Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); + if (permanent != null) { + permanent.damage(damage, source.getSourceId(), game, true, false); + } + else{ + Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetPlayer != null) { + targetPlayer.damage(damage, source.getSourceId(), game, false, true); + } + } + + TargetCard target = new TargetCard(Constants.Zone.PICK, new FilterCard("card to put on the bottom of your library")); + target.setRequired(true); + while (cards.size() > 1) { + player.choose(Outcome.Neutral, cards, target, game); + Card card = cards.get(target.getFirstTarget(), game); + if (card != null) { + cards.remove(card); + card.moveToZone(Constants.Zone.PICK, source.getId(), game, false); + } + target.clearChosen(); + } + + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/planarchaos/SimianSpiritGuide.java b/Mage.Sets/src/mage/sets/planarchaos/SimianSpiritGuide.java new file mode 100644 index 00000000000..c4fc6fe9326 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planarchaos/SimianSpiritGuide.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.sets.planarchaos; + +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.costs.CostImpl; +import mage.abilities.effects.common.BasicManaEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author Plopman + */ +public class SimianSpiritGuide extends CardImpl { + + public SimianSpiritGuide(UUID ownerId) { + super(ownerId, 122, "Simian Spirit Guide", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "PLC"; + this.subtype.add("Ape"); + this.subtype.add("Spirit"); + + this.color.setRed(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Exile Simian Spirit Guide from your hand: Add {R} to your mana pool. + this.addAbility(new SimpleManaAbility(Constants.Zone.HAND, new BasicManaEffect(Mana.RedMana), new ExileSourceFromHandCost())); + } + + public SimianSpiritGuide(final SimianSpiritGuide card) { + super(card); + } + + @Override + public SimianSpiritGuide copy() { + return new SimianSpiritGuide(this); + } +} + + +class ExileSourceFromHandCost extends CostImpl { + + public ExileSourceFromHandCost() { + this.text = "Exile {this} from your hand"; + } + + public ExileSourceFromHandCost(ExileSourceFromHandCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Card card = game.getCard(sourceId); + Player player = game.getPlayer(controllerId); + if (player != null && player.getHand().contains(sourceId) && card != null) { + paid = card.moveToExile(ability.getSourceId(), "from Hand", ability.getSourceId(), game); + } + return paid; + } + + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + Player player = game.getPlayer(controllerId); + if (player != null && player.getHand().contains(sourceId)) { + return true; + } + return false; + } + + @Override + public ExileSourceFromHandCost copy() { + return new ExileSourceFromHandCost(this); + } + +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/keyword/CyclingAbility.java b/Mage/src/mage/abilities/keyword/CyclingAbility.java index 466c8a8cb7e..e2cb272592d 100644 --- a/Mage/src/mage/abilities/keyword/CyclingAbility.java +++ b/Mage/src/mage/abilities/keyword/CyclingAbility.java @@ -32,6 +32,8 @@ import mage.Constants.Outcome; import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.Costs; import mage.abilities.costs.common.DiscardSourceCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.effects.OneShotEffect; @@ -45,13 +47,17 @@ import mage.players.Player; */ public class CyclingAbility extends ActivatedAbilityImpl { - public CyclingAbility(ManaCosts costs) { - super(Zone.HAND, new CycleEffect(), costs); + private Cost cost; + + public CyclingAbility(Cost cost) { + super(Zone.HAND, new CycleEffect(), cost); this.addCost(new DiscardSourceCost()); + this.cost = cost; } public CyclingAbility(final CyclingAbility ability) { super(ability); + this.cost = ability.cost; } @Override @@ -61,7 +67,14 @@ public class CyclingAbility extends ActivatedAbilityImpl { @Override public String getRule() { - return "Cycling " + getManaCostsToPay().getText()+ " (" + super.getRule() + ")"; + String rule = ""; + if(cost instanceof ManaCosts){ + rule = "Cycling " + cost.getText() + " (" + super.getRule() + ")"; + } + else{ + rule = "Cycling-" + cost.getText() + " (" + super.getRule() + ")"; + } + return rule; } }