diff --git a/Mage.Sets/src/mage/sets/apocalypse/Index.java b/Mage.Sets/src/mage/sets/apocalypse/Index.java new file mode 100644 index 00000000000..162ab5dc82c --- /dev/null +++ b/Mage.Sets/src/mage/sets/apocalypse/Index.java @@ -0,0 +1,61 @@ +/* + * 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.apocalypse; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.abilities.effects.common.LookLibraryControllerEffect; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class Index extends CardImpl { + + public Index(UUID ownerId) { + super(ownerId, 25, "Index", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); + this.expansionSetCode = "APC"; + this.color.setBlue(true); + + // Look at the top five cards of your library, then put them back in any order. + this.getSpellAbility().addEffect(new LookLibraryControllerEffect(5)); + } + + public Index(final Index card) { + super(card); + } + + @Override + public Index copy() { + return new Index(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/CranialExtraction.java b/Mage.Sets/src/mage/sets/championsofkamigawa/CranialExtraction.java new file mode 100644 index 00000000000..e54d3c6b4b1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/CranialExtraction.java @@ -0,0 +1,129 @@ +/* + * Copyright 2011 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardsImpl; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.game.Game; +import mage.players.Player; +import mage.sets.Sets; +import mage.target.TargetPlayer; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class CranialExtraction extends CardImpl { + + public CranialExtraction(UUID ownerId) { + super(ownerId, 105, "Cranial Extraction", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{B}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Arcane"); + this.color.setBlack(true); + + /* Name a nonland card. Search target player's graveyard, hand, and library for + * all cards with that name and exile them. Then that player shuffles his or her library. */ + this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().addEffect(new CranialExtractionEffect()); + } + + public CranialExtraction(final CranialExtraction card) { + super(card); + } + + @Override + public CranialExtraction copy() { + return new CranialExtraction(this); + } + +} + +class CranialExtractionEffect extends OneShotEffect { + + public CranialExtractionEffect() { + super(Outcome.Exile); + staticText = "Name a nonland card. Search target player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library"; + } + + public CranialExtractionEffect(final CranialExtractionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(source)); + Player controller = game.getPlayer(source.getControllerId()); + if (player != null && controller != null) { + Choice cardChoice = new ChoiceImpl(); + cardChoice.setChoices(Sets.getNonLandCardNames()); + cardChoice.clearChoice(); + + while (!controller.choose(Outcome.Exile, cardChoice, game)) { + game.debugMessage("player canceled choosing name. retrying."); + } + + String cardName = cardChoice.getChoice(); + game.informPlayers("CranialExtraction, named card: [" + cardName + "]"); + for (Card card: player.getGraveyard().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + for (Card card: player.getHand().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + for (Card card: player.getLibrary().getCards(game)) { + if (card.getName().equals(cardName)) { + card.moveToExile(null, "", source.getId(), game); + } + } + controller.lookAtCards("CranialExtraction Hand", player.getHand(), game); + controller.lookAtCards("CranialExtraction Library", new CardsImpl(Zone.PICK, player.getLibrary().getCards(game)), game); + player.shuffleLibrary(game); + } + return true; + } + + @Override + public CranialExtractionEffect copy() { + return new CranialExtractionEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/EightAndAHalfTale.java b/Mage.Sets/src/mage/sets/championsofkamigawa/EightAndAHalfTale.java new file mode 100644 index 00000000000..d8ba337399b --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/EightAndAHalfTale.java @@ -0,0 +1,92 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.filter.FilterCard; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author LevelX + */ +public class EightAndAHalfTale extends CardImpl { + + private final static FilterCard filter = new FilterCard("white"); + + static { + filter.setUseColor(true); + filter.getColor().setWhite(true); + } + + public EightAndAHalfTale(UUID ownerId) { + super(ownerId, 8, "Eight-and-a-Half-Tails", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{W}{W}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Fox"); + this.subtype.add("Cleric"); + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + // {1}{W}: Target permanent you control gains protection from white until end of turn. + Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect( + new ProtectionAbility(filter), Constants.Duration.EndOfTurn), new ManaCostsImpl("{1}{W}")); + ability1.addTarget(new TargetControlledPermanent()); + this.addAbility(ability1); + // {1}: Target spell or permanent becomes white until end of turn. + Ability ability2 = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new SetCardColorTargetEffect( + ObjectColor.WHITE, Constants.Duration.EndOfTurn),new ManaCostsImpl("{1}")); + ability2.addTarget(new TargetSpellOrPermanent()); + this.addAbility(ability2); + + } + + public EightAndAHalfTale(final EightAndAHalfTale card) { + super(card); + } + + @Override + public EightAndAHalfTale copy() { + return new EightAndAHalfTale(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/EtherealHaze.java b/Mage.Sets/src/mage/sets/championsofkamigawa/EtherealHaze.java new file mode 100644 index 00000000000..50a6b6a6d89 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/EtherealHaze.java @@ -0,0 +1,64 @@ +/* + * Copyright 2011 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.abilities.effects.common.PreventAllDamageEffect; +import mage.cards.CardImpl; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author LevelX + */ +public class EtherealHaze extends CardImpl { + + public EtherealHaze (UUID ownerId) { + super(ownerId, 9, "Ethereal Haze", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "CHK"; + this.color.setWhite(true); + + // Prevent all damage that would be dealt by creatures this turn. + this.getSpellAbility().addEffect(new PreventAllDamageEffect(new FilterCreaturePermanent("creatures"), Duration.EndOfTurn, false)); + + } + + public EtherealHaze (final EtherealHaze card) { + super(card); + } + + @Override + public EtherealHaze copy() { + return new EtherealHaze(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/Hankyu.java b/Mage.Sets/src/mage/sets/championsofkamigawa/Hankyu.java new file mode 100644 index 00000000000..52cdfa5e8b6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/Hankyu.java @@ -0,0 +1,208 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants.AttachmentType; +import mage.Constants.CardType; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.counters.common.AimCounter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author North + */ +public class Hankyu extends CardImpl { + + public Hankyu(UUID ownerId) { + super(ownerId, 253, "Hankyu", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Equipment"); + + /* Equipped creature has "{T}: Put an aim counter on Hankyu" and */ + SimpleActivatedAbility ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HankyuAddCounterEffect(this.getId()), new TapSourceCost()); + ability1.setSourceId(this.getId()); // to know where to put the counters on + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability1, AttachmentType.EQUIPMENT))); + + /* "{T}, Remove all aim counters from Hankyu: This creature deals + * damage to target creature or player equal to the number of + * aim counters removed this way." */ + SimpleActivatedAbility ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HankyuDealsDamageEffect(), new TapSourceCost()); + ability2.addCost(new HankyuCountersSourceCost(this.getId())); + ability2.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability2, AttachmentType.EQUIPMENT))); + + // Equip {4} ({4}: Attach to target creature you control. Equip only as a sorcery.) + this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(4))); + } + + public Hankyu(final Hankyu card) { + super(card); + } + + @Override + public Hankyu copy() { + return new Hankyu(this); + } +} + +class HankyuAddCounterEffect extends OneShotEffect { + + private UUID effectGivingEquipmentId; + + public HankyuAddCounterEffect(UUID effectGivingEquipmentId) { + super(Outcome.Benefit); + this.effectGivingEquipmentId = effectGivingEquipmentId; + staticText = "Put an aim counter on Hankyu"; + } + + public HankyuAddCounterEffect(final HankyuAddCounterEffect effect) { + super(effect); + this.effectGivingEquipmentId = effect.effectGivingEquipmentId; + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent equipment = game.getPermanent(this.effectGivingEquipmentId); + if (equipment != null) { + equipment.addCounters(new AimCounter(), game); + } + return true; + } + + @Override + public HankyuAddCounterEffect copy() { + return new HankyuAddCounterEffect(this); + } + + +} + + +class HankyuDealsDamageEffect extends OneShotEffect { + + public HankyuDealsDamageEffect() { + super(Outcome.Damage); + staticText = "This creature deals damage to target creature or player equal to the number of aim counters removed this way"; + } + + public HankyuDealsDamageEffect(final HankyuDealsDamageEffect effect) { + super(effect); + } + + @Override + public HankyuDealsDamageEffect copy() { + return new HankyuDealsDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + // get the number of removed counters as damage amount + HankyuCountersSourceCost cost = (HankyuCountersSourceCost) source.getCosts().get(1); + if (cost != null) { + int damageAmount = cost.getRemovedCounters(); + if (damageAmount > 0) { + + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + permanent.damage(damageAmount, source.getSourceId(), game, true, false); + } + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + player.damage(damageAmount, source.getSourceId(), game, false, true); + } + } + return true; + } + return false; + } + +} + +class HankyuCountersSourceCost extends CostImpl { + + private int removedCounters; + private UUID effectGivingEquipmentId; + + public HankyuCountersSourceCost(UUID effectGivingEquipmentId) { + super(); + this.removedCounters = 0; + this.effectGivingEquipmentId = effectGivingEquipmentId; + this.text = "Remove all aim counters from Hankyu"; + } + + public HankyuCountersSourceCost(HankyuCountersSourceCost cost) { + super(cost); + this.effectGivingEquipmentId = cost.effectGivingEquipmentId; + this.removedCounters = cost.removedCounters; + } + + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + return true; + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Permanent equipment = game.getPermanent(this.effectGivingEquipmentId); + this.removedCounters = equipment.getCounters().getCount(CounterType.AIM); + if (equipment != null && this.removedCounters > 0) { + equipment.removeCounters("aim", this.removedCounters, game); + } + this.paid = true; + return true; + } + + @Override + public HankyuCountersSourceCost copy() { + return new HankyuCountersSourceCost(this); + } + + public int getRemovedCounters() { + return this.removedCounters; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/HeWhoHungers.java b/Mage.Sets/src/mage/sets/championsofkamigawa/HeWhoHungers.java new file mode 100644 index 00000000000..44c7645e187 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/HeWhoHungers.java @@ -0,0 +1,144 @@ +/* + * 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.championsofkamigawa; + +/** + * + * @author LevelX + */ + + +import java.util.UUID; + + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.SoulshiftAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.FilterCard; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetOpponent; + +/** + * @author LevelX + */ +public class HeWhoHungers extends CardImpl { + + private final static FilterControlledPermanent filter = new FilterControlledPermanent("a Spirit"); + + static { + filter.getSubtype().add("Spirit"); + filter.setScopeSubtype(Filter.ComparisonScope.Any); + } + + public HeWhoHungers(UUID ownerId) { + super(ownerId, 114, "He Who Hungers", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + //Flying + this.addAbility(FlyingAbility.getInstance()); + + /* {1}, Sacrifice a Spirit: Target opponent reveals his or her hand. You choose a card from it. + * That player discards that card. Activate this ability only any time you could cast a sorcery. */ + Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new HeWhoHungersEffect(), new ManaCostsImpl("{1}")); + ability.addTarget(new TargetOpponent()); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.addAbility(ability); + + //Soulshift 4 (When this creature dies, you may return target Spirit card with converted mana cost 4 or less from your graveyard to your hand.) + this.addAbility(new SoulshiftAbility(4)); + } + + public HeWhoHungers(final HeWhoHungers card) { + super(card); + } + + @Override + public HeWhoHungers copy() { + return new HeWhoHungers(this); + } + +} + +class HeWhoHungersEffect extends OneShotEffect { + + public HeWhoHungersEffect() { + super(Constants.Outcome.Discard); + staticText = "Target opponent reveals his or her hand. You choose a card from it. That player discards that card"; + } + + public HeWhoHungersEffect(final HeWhoHungersEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + player.revealCards("He Who Hungers", player.getHand(), game); + Player you = game.getPlayer(source.getControllerId()); + if (you != null) { + TargetCard target = new TargetCard(Constants.Zone.PICK, new FilterCard()); + target.setRequired(true); + if (you.choose(Constants.Outcome.Benefit, player.getHand(), target, game)) { + Card card = player.getHand().get(target.getFirstTarget(), game); + if (card != null) { + return player.discard(card, source, game); + } + } + } + } + return false; + } + + @Override + public HeWhoHungersEffect copy() { + return new HeWhoHungersEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SenseisDiviningTop.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SenseisDiviningTop.java new file mode 100644 index 00000000000..7ad3295a72d --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SenseisDiviningTop.java @@ -0,0 +1,97 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants.CardType; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +import mage.Constants.Zone; +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.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.LookLibraryControllerEffect; +import mage.cards.CardImpl; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * @author LevelX + */ +public class SenseisDiviningTop extends CardImpl { + + public SenseisDiviningTop(UUID ownerId) { + super(ownerId, 268, "Sensei's Divining Top", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "CHK"; + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(3),new ManaCostsImpl("{1}"))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardControllerEffect(1),new TapSourceCost()); + ability.addEffect(new SenseisDiviningTopEffect()); + this.addAbility(ability); + } + + public SenseisDiviningTop(final SenseisDiviningTop card) { + super(card); + } + + @Override + public SenseisDiviningTop copy() { + return new SenseisDiviningTop(this); + } + +} + +class SenseisDiviningTopEffect extends OneShotEffect { + + public SenseisDiviningTopEffect() { + super(Outcome.ReturnToHand); + staticText = ", then put Sensei's Divining Top on top of its owner's library"; + } + + public SenseisDiviningTopEffect(final SenseisDiviningTopEffect effect) { + super(effect); + } + + @Override + public SenseisDiviningTopEffect copy() { + return new SenseisDiviningTopEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + return permanent.moveToZone(Zone.LIBRARY, source.getId(), game, true); + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/guildpact/CrystalSeer.java b/Mage.Sets/src/mage/sets/guildpact/CrystalSeer.java new file mode 100644 index 00000000000..88e984600e6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/CrystalSeer.java @@ -0,0 +1,76 @@ + +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.guildpact; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.LookLibraryControllerEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class CrystalSeer extends CardImpl { + + public CrystalSeer (UUID ownerId) { + super(ownerId, 23, "Crystal Seer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{U}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Vedalken"); + this.subtype.add("Wizard"); + this.color.setBlue(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Crystal Seer enters the battlefield, look at the top four cards of your library, then put them back in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryControllerEffect(4))); + + // {4}{U}: Return Crystal Seer to its owner's hand. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(), new ManaCostsImpl("{4}{U}"))); + } + + public CrystalSeer (final CrystalSeer card) { + super(card); + } + + @Override + public CrystalSeer copy() { + return new CrystalSeer(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/innistrad/Moonmist.java b/Mage.Sets/src/mage/sets/innistrad/Moonmist.java index 62272dd84f7..ba340d6b80a 100644 --- a/Mage.Sets/src/mage/sets/innistrad/Moonmist.java +++ b/Mage.Sets/src/mage/sets/innistrad/Moonmist.java @@ -34,7 +34,7 @@ import mage.Constants.Outcome; import mage.Constants.Rarity; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PreventAllCombatDamageEffect; +import mage.abilities.effects.common.PreventAllDamageEffect; import mage.cards.CardImpl; import mage.filter.Filter.ComparisonScope; import mage.filter.common.FilterCreaturePermanent; @@ -64,7 +64,7 @@ public class Moonmist extends CardImpl { // Transform all Humans. Prevent all combat damage that would be dealt this turn by creatures other than Werewolves and Wolves. this.getSpellAbility().addEffect(new MoonmistEffect()); - this.getSpellAbility().addEffect(new PreventAllCombatDamageEffect(filter, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new PreventAllDamageEffect(filter, Duration.EndOfTurn, true)); } public Moonmist(final Moonmist card) { diff --git a/Mage.Sets/src/mage/sets/lorwyn/GiltLeafSeer.java b/Mage.Sets/src/mage/sets/lorwyn/GiltLeafSeer.java index 941d7952ee0..1b367a7f1a9 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/GiltLeafSeer.java +++ b/Mage.Sets/src/mage/sets/lorwyn/GiltLeafSeer.java @@ -28,7 +28,6 @@ package mage.sets.lorwyn; import mage.Constants.CardType; -import mage.Constants.Outcome; import mage.Constants.Rarity; import mage.Constants.Zone; import mage.MageInt; @@ -36,17 +35,10 @@ 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.players.Player; -import mage.target.TargetCard; import java.util.UUID; +import mage.abilities.effects.common.LookLibraryControllerEffect; /** * @@ -65,7 +57,7 @@ public class GiltLeafSeer extends CardImpl { this.toughness = new MageInt(2); // {G}, {tap}: Look at the top two cards of your library, then put them back in any order. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GiltLeafSeerEffect(), new ManaCostsImpl("{G}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(2), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -78,58 +70,4 @@ public class GiltLeafSeer extends CardImpl { public GiltLeafSeer copy() { return new GiltLeafSeer(this); } -} - -class GiltLeafSeerEffect extends OneShotEffect { - - public GiltLeafSeerEffect() { - super(Outcome.Neutral); - this.staticText = "look at the top two cards of your library, then put them back in any order"; - } - - public GiltLeafSeerEffect(final GiltLeafSeerEffect effect) { - super(effect); - } - - @Override - public GiltLeafSeerEffect copy() { - return new GiltLeafSeerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - - Cards cards = new CardsImpl(Zone.PICK); - int count = Math.min(player.getLibrary().size(), 2); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - game.setZone(card.getId(), Zone.PICK); - } - } - player.lookAtCards("Sage Owl", cards, game); - - TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top 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(Zone.LIBRARY, source.getId(), game, true); - } - target.clearChosen(); - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); - } - - return true; - } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/lorwyn/InkfathomDivers.java b/Mage.Sets/src/mage/sets/lorwyn/InkfathomDivers.java new file mode 100644 index 00000000000..32fc1dd3544 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/InkfathomDivers.java @@ -0,0 +1,73 @@ +/* + * 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.lorwyn; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.LookLibraryControllerEffect; +import mage.abilities.keyword.IslandwalkAbility; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class InkfathomDivers extends CardImpl { + + public InkfathomDivers (UUID ownerId) { + super(ownerId, 70, "Inkfathom Divers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Merfolk"); + this.subtype.add("Soldier"); + this.color.setBlue(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Islandwalk + this.addAbility(new IslandwalkAbility()); + + // When Inkfathom Divers enters the battlefield, look at the top four cards of your library, then put them back in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryControllerEffect(4))); + + } + + public InkfathomDivers (final InkfathomDivers card) { + super(card); + } + + @Override + public InkfathomDivers copy() { + return new InkfathomDivers(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/magic2010/Fog.java b/Mage.Sets/src/mage/sets/magic2010/Fog.java index 17ad89a3df7..2a30570f8d0 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Fog.java +++ b/Mage.Sets/src/mage/sets/magic2010/Fog.java @@ -32,7 +32,7 @@ import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Rarity; -import mage.abilities.effects.common.PreventAllCombatDamageEffect; +import mage.abilities.effects.common.PreventAllDamageEffect; import mage.cards.CardImpl; /** @@ -45,7 +45,7 @@ public class Fog extends CardImpl { super(ownerId, 182, "Fog", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); this.expansionSetCode = "M10"; this.color.setGreen(true); - this.getSpellAbility().addEffect(new PreventAllCombatDamageEffect(Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new PreventAllDamageEffect(Duration.EndOfTurn, true)); } public Fog(final Fog card) { diff --git a/Mage.Sets/src/mage/sets/magic2010/Ponder.java b/Mage.Sets/src/mage/sets/magic2010/Ponder.java index 477219e78bd..62a2aa71714 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Ponder.java +++ b/Mage.Sets/src/mage/sets/magic2010/Ponder.java @@ -29,20 +29,11 @@ package mage.sets.magic2010; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardControllerEffect; -import mage.cards.Card; +import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.cards.CardImpl; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; /** * @author nantuko @@ -56,7 +47,7 @@ public class Ponder extends CardImpl { this.color.setBlue(true); // Look at the top three cards of your library, then put them back in any order. You may shuffle your library. - this.getSpellAbility().addEffect(new PonderEffect()); + this.getSpellAbility().addEffect(new LookLibraryControllerEffect(3, true)); // Draw a card. this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); } @@ -69,62 +60,4 @@ public class Ponder extends CardImpl { public Ponder copy() { return new Ponder(this); } -} - -class PonderEffect extends OneShotEffect { - - protected static FilterCard filter = new FilterCard("card to put on the top of your library"); - - public PonderEffect() { - super(Constants.Outcome.Benefit); - staticText = "Look at the top three cards of your library, then put them back in any order. You may shuffle your library"; - } - - public PonderEffect(final PonderEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Cards cards = new CardsImpl(Constants.Zone.PICK); - int count = Math.min(3, player.getLibrary().size()); - if (count == 0) { - return false; - } - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - game.setZone(card.getId(), Constants.Zone.PICK); - } - if (cards.size() > 1) { - TargetCard target2 = new TargetCard(Constants.Zone.PICK, filter); - target2.setRequired(true); - while (cards.size() > 1) { - player.choose(Constants.Outcome.Benefit, cards, target2, game); - Card card = cards.get(target2.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - card.moveToZone(Constants.Zone.LIBRARY, source.getId(), game, true); - } - target2.clearChosen(); - } - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Constants.Zone.LIBRARY, source.getId(), game, true); - } - if (player.chooseUse(Constants.Outcome.Benefit, "Shuffle you library?", game)) { - player.shuffleLibrary(game); - } - return true; - } - - @Override - public PonderEffect copy() { - return new PonderEffect(this); - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magic2010/SageOwl.java b/Mage.Sets/src/mage/sets/magic2010/SageOwl.java index 3f4b49e16af..a96f7207d22 100644 --- a/Mage.Sets/src/mage/sets/magic2010/SageOwl.java +++ b/Mage.Sets/src/mage/sets/magic2010/SageOwl.java @@ -29,22 +29,12 @@ package mage.sets.magic2010; import java.util.UUID; import mage.Constants.CardType; -import mage.Constants.Outcome; import mage.Constants.Rarity; -import mage.Constants.Zone; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.keyword.FlyingAbility; -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.players.Player; -import mage.target.TargetCard; /** * @@ -62,7 +52,8 @@ public class SageOwl extends CardImpl { this.toughness = new MageInt(1); this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SageOwlEffect())); + // When Sage Owl enters the battlefield, look at the top four cards of your library, then put them back in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryControllerEffect(4))); } public SageOwl(final SageOwl card) { @@ -73,58 +64,4 @@ public class SageOwl extends CardImpl { public SageOwl copy() { return new SageOwl(this); } -} - -class SageOwlEffect extends OneShotEffect { - - public SageOwlEffect() { - super(Outcome.Neutral); - this.staticText = "look at the top four cards of your library, then put them back in any order"; - } - - public SageOwlEffect(final SageOwlEffect effect) { - super(effect); - } - - @Override - public SageOwlEffect copy() { - return new SageOwlEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - - Cards cards = new CardsImpl(Zone.PICK); - int count = Math.min(player.getLibrary().size(), 4); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - game.setZone(card.getId(), Zone.PICK); - } - } - player.lookAtCards("Sage Owl", cards, game); - - TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top 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(Zone.LIBRARY, source.getId(), game, true); - } - target.clearChosen(); - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); - } - - return true; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/magic2011/Incite.java b/Mage.Sets/src/mage/sets/magic2011/Incite.java index 467ceadfe15..1e72de37885 100644 --- a/Mage.Sets/src/mage/sets/magic2011/Incite.java +++ b/Mage.Sets/src/mage/sets/magic2011/Incite.java @@ -29,15 +29,18 @@ package mage.sets.magic2011; import java.util.UUID; +import mage.Constants; import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Layer; import mage.Constants.Outcome; import mage.Constants.Rarity; import mage.Constants.SubLayer; +import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.AttacksIfAbleTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; import mage.cards.CardImpl; import mage.game.Game; import mage.game.permanent.Permanent; @@ -53,8 +56,10 @@ public class Incite extends CardImpl { super(ownerId, 145, "Incite", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}"); this.expansionSetCode = "M11"; this.color.setRed(true); - this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new InciteEffect()); + // Target creature becomes red until end of turn and attacks this turn if able. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); +// this.getSpellAbility().addEffect(new InciteEffect()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.RED, Constants.Duration.EndOfTurn, "Target creature becomes red until end of turn")); this.getSpellAbility().addEffect(new AttacksIfAbleTargetEffect(Duration.EndOfTurn)); } @@ -68,34 +73,34 @@ public class Incite extends CardImpl { } } -class InciteEffect extends ContinuousEffectImpl { - - public InciteEffect() { - super(Duration.EndOfTurn, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Detriment); - staticText = "Target creature becomes red until end of turn"; - } - - public InciteEffect(final InciteEffect effect) { - super(effect); - } - - @Override - public InciteEffect copy() { - return new InciteEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - permanent.getColor().setRed(true); - permanent.getColor().setWhite(false); - permanent.getColor().setGreen(false); - permanent.getColor().setBlue(false); - permanent.getColor().setBlack(false); - return true; - } - return false; - } - -} +//class InciteEffect extends ContinuousEffectImpl { +// +// public InciteEffect() { +// super(Duration.EndOfTurn, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Detriment); +// staticText = "Target creature becomes red until end of turn"; +// } +// +// public InciteEffect(final InciteEffect effect) { +// super(effect); +// } +// +// @Override +// public InciteEffect copy() { +// return new InciteEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// Permanent permanent = game.getPermanent(source.getFirstTarget()); +// if (permanent != null) { +// permanent.getColor().setRed(true); +// permanent.getColor().setWhite(false); +// permanent.getColor().setGreen(false); +// permanent.getColor().setBlue(false); +// permanent.getColor().setBlack(false); +// return true; +// } +// return false; +// } +// +//} diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/GlissaTheTraitor.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/GlissaTheTraitor.java index 890d12082fb..daed28e5c65 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/GlissaTheTraitor.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/GlissaTheTraitor.java @@ -37,7 +37,7 @@ import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.keyword.DeathtouchAbility; -import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; import mage.filter.Filter; import mage.filter.FilterCard; @@ -62,8 +62,11 @@ public class GlissaTheTraitor extends CardImpl { this.color.setGreen(true); this.power = new MageInt(3); this.toughness = new MageInt(3); - this.addAbility(FlyingAbility.getInstance()); + // First strike, + this.addAbility(FirstStrikeAbility.getInstance()); + // Deathtouch this.addAbility(DeathtouchAbility.getInstance()); + // Whenever a creature an opponent controls dies, you may return target artifact card from your graveyard to your hand. this.addAbility(new GlissaTheTraitorTriggeredAbility()); } @@ -113,6 +116,6 @@ class GlissaTheTraitorTriggeredAbility extends TriggeredAbilityImpl { // Prevent all combat damage that would be dealt this turn by attacking // creatures. this.getSpellAbility().addEffect( - new PreventAllCombatDamageEffect(filter, Duration.EndOfTurn)); + new PreventAllDamageEffect(filter, Duration.EndOfTurn, true)); } public HarmlessAssault(final HarmlessAssault card) { diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/BluntTheAssault.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/BluntTheAssault.java index 16a7e0e32f5..526064f3875 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/BluntTheAssault.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/BluntTheAssault.java @@ -35,7 +35,7 @@ import mage.Constants.CardType; import mage.Constants.Rarity; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.PreventAllCombatDamageEffect; +import mage.abilities.effects.common.PreventAllDamageEffect; import mage.cards.CardImpl; import mage.filter.FilterPermanent; @@ -56,7 +56,7 @@ public class BluntTheAssault extends CardImpl { this.expansionSetCode = "SOM"; this.color.setGreen(true); this.getSpellAbility().addEffect(new GainLifeEffect(new PermanentsOnBattlefieldCount(filter))); - this.getSpellAbility().addEffect(new PreventAllCombatDamageEffect(Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new PreventAllDamageEffect(Constants.Duration.EndOfTurn, true)); } public BluntTheAssault (final BluntTheAssault card) { diff --git a/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java new file mode 100644 index 00000000000..fb35c9c6e11 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/AphoticWisps.java @@ -0,0 +1,72 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.ObjectColor; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.abilities.keyword.FearAbility; +import mage.cards.CardImpl; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class AphoticWisps extends CardImpl { + + public AphoticWisps (UUID ownerId) { + super(ownerId, 55, "Aphotic Wisps", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{B}"); + this.expansionSetCode = "SHM"; + this.color.setBlack(true); + // Target creature becomes black and gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.) + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.BLACK, Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FearAbility.getInstance(), Constants.Duration.EndOfTurn)); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); + } + + public AphoticWisps (final AphoticWisps card) { + super(card); + } + + @Override + public AphoticWisps copy() { + return new AphoticWisps(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/shadowmoor/CeruleanWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/CeruleanWisps.java new file mode 100644 index 00000000000..ce7741c4a12 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/CeruleanWisps.java @@ -0,0 +1,71 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.ObjectColor; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.cards.CardImpl; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class CeruleanWisps extends CardImpl { + + public CeruleanWisps (UUID ownerId) { + super(ownerId, 31, "Cerulean Wisps", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{U}"); + this.expansionSetCode = "SHM"; + this.color.setBlue(true); + // Target creature becomes blue until end of turn. Untap that creature. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.BLUE, Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect()); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); + } + + public CeruleanWisps (final CeruleanWisps card) { + super(card); + } + + @Override + public CeruleanWisps copy() { + return new CeruleanWisps(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/shadowmoor/CrimsonWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/CrimsonWisps.java new file mode 100644 index 00000000000..872adff863d --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/CrimsonWisps.java @@ -0,0 +1,73 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.ObjectColor; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class CrimsonWisps extends CardImpl { + + public CrimsonWisps (UUID ownerId) { + super(ownerId, 88, "Crimson Wisps", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "SHM"; + this.color.setRed(true); + // Target creature becomes red and gains haste until end of turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.RED, Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Constants.Duration.EndOfTurn)); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); + } + + public CrimsonWisps (final CrimsonWisps card) { + super(card); + } + + @Override + public CrimsonWisps copy() { + return new CrimsonWisps(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/shadowmoor/NiveousWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/NiveousWisps.java new file mode 100644 index 00000000000..c3e28b7d405 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/NiveousWisps.java @@ -0,0 +1,71 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.ObjectColor; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.cards.CardImpl; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class NiveousWisps extends CardImpl { + + public NiveousWisps (UUID ownerId) { + super(ownerId, 15, "Niveous Wisps", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "SHM"; + this.color.setWhite(true); + // Target creature becomes white until end of turn. Tap that creature. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.WHITE, Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new TapTargetEffect()); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); + } + + public NiveousWisps (final NiveousWisps card) { + super(card); + } + + @Override + public NiveousWisps copy() { + return new NiveousWisps(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/shadowmoor/ViridescentWisps.java b/Mage.Sets/src/mage/sets/shadowmoor/ViridescentWisps.java new file mode 100644 index 00000000000..41a44d897de --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/ViridescentWisps.java @@ -0,0 +1,71 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.ObjectColor; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.continious.BoostTargetEffect; +import mage.abilities.effects.common.continious.SetCardColorTargetEffect; +import mage.cards.CardImpl; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class ViridescentWisps extends CardImpl { + + public ViridescentWisps (UUID ownerId) { + super(ownerId, 132, "Viridescent Wisps", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); + this.expansionSetCode = "SHM"; + this.color.setGreen(true); + // Target creature becomes green and gets +1/+0 until end of turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SetCardColorTargetEffect(ObjectColor.GREEN, Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new BoostTargetEffect(1,0, Constants.Duration.EndOfTurn)); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardControllerEffect(1)); + } + + public ViridescentWisps (final ViridescentWisps card) { + super(card); + } + + @Override + public ViridescentWisps copy() { + return new ViridescentWisps(this); + } + +} + diff --git a/Mage.Sets/src/mage/sets/shardsofalara/Angelsong.java b/Mage.Sets/src/mage/sets/shardsofalara/Angelsong.java index 9cdf89f2d49..7cd5503e2a9 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/Angelsong.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/Angelsong.java @@ -33,7 +33,7 @@ import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Rarity; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PreventAllCombatDamageEffect; +import mage.abilities.effects.common.PreventAllDamageEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.CardImpl; @@ -47,7 +47,7 @@ public class Angelsong extends CardImpl { super(ownerId, 4, "Angelsong", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.expansionSetCode = "ALA"; this.color.setWhite(true); - this.getSpellAbility().addEffect(new PreventAllCombatDamageEffect(Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new PreventAllDamageEffect(Duration.EndOfTurn, true)); this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/KnightCaptainOfEos.java b/Mage.Sets/src/mage/sets/shardsofalara/KnightCaptainOfEos.java index 2634d9e72f8..e5f69df79cc 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/KnightCaptainOfEos.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/KnightCaptainOfEos.java @@ -38,7 +38,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.PreventAllCombatDamageEffect; +import mage.abilities.effects.common.PreventAllDamageEffect; import mage.cards.CardImpl; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.permanent.token.SoldierToken; @@ -67,7 +67,7 @@ public class KnightCaptainOfEos extends CardImpl { this.toughness = new MageInt(2); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken(), 2), false)); - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventAllCombatDamageEffect(Duration.EndOfTurn), new ManaCostsImpl("{W}")); + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventAllDamageEffect(Duration.EndOfTurn, true), new ManaCostsImpl("{W}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/tenth/Discombobulate.java b/Mage.Sets/src/mage/sets/tenth/Discombobulate.java new file mode 100644 index 00000000000..e89047548b9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/tenth/Discombobulate.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.sets.tenth; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.LookLibraryControllerEffect; +import mage.cards.CardImpl; +import mage.target.TargetSpell; + +/** + * + * @author LevelX + */ +public class Discombobulate extends CardImpl { + + public Discombobulate(UUID ownerId) { + super(ownerId, 81, "Discombobulate", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); + this.expansionSetCode = "10E"; + this.color.setBlue(true); + // Counter target spell. Look at the top four cards of your library, then put them back in any order. + this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addEffect(new LookLibraryControllerEffect(4)); + } + + public Discombobulate(final Discombobulate card) { + super(card); + } + + @Override + public Discombobulate copy() { + return new Discombobulate(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/tenth/HiddenHorror.java b/Mage.Sets/src/mage/sets/tenth/HiddenHorror.java index 533394375a6..e393598177b 100644 --- a/Mage.Sets/src/mage/sets/tenth/HiddenHorror.java +++ b/Mage.Sets/src/mage/sets/tenth/HiddenHorror.java @@ -51,7 +51,7 @@ public class HiddenHorror extends CardImpl { this.color.setBlack(true); this.power = new MageInt(4); this.toughness = new MageInt(4); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard()))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard("a creature card")))))); } public HiddenHorror(final HiddenHorror card) { diff --git a/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java b/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java index da98ecc6f25..855ed826829 100644 --- a/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java +++ b/Mage.Sets/src/mage/sets/worldwake/HalimarDepths.java @@ -30,22 +30,12 @@ package mage.sets.worldwake; import java.util.UUID; import mage.Constants.CardType; -import mage.Constants.Outcome; import mage.Constants.Rarity; -import mage.Constants.Zone; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.mana.BlueManaAbility; -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.players.Player; -import mage.target.TargetCard; /** * @@ -56,8 +46,10 @@ public class HalimarDepths extends CardImpl { public HalimarDepths(UUID ownerId) { super(ownerId, 137, "Halimar Depths", Rarity.COMMON, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "WWK"; - this.addAbility(new EntersBattlefieldTappedAbility()); - this.addAbility(new EntersBattlefieldTriggeredAbility(new HalimarDepthsEffect())); + // Halimar Depths enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + // When Halimar Depths enters the battlefield, look at the top three cards of your library, then put them back in any order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryControllerEffect(3))); this.addAbility(new BlueManaAbility()); } @@ -71,57 +63,3 @@ public class HalimarDepths extends CardImpl { } } - -class HalimarDepthsEffect extends OneShotEffect { - - protected static FilterCard filter2 = new FilterCard("card to put on the top of your library"); - - public HalimarDepthsEffect() { - super(Outcome.Benefit); - staticText = "look at the top three cards of your library, then put them back in any order"; - } - - public HalimarDepthsEffect(final HalimarDepthsEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Cards cards = new CardsImpl(Zone.PICK); - int count = Math.min(player.getLibrary().size(), 3); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - game.setZone(card.getId(), Zone.PICK); - } - } - if (cards.size() > 1) { - TargetCard target2 = new TargetCard(Zone.PICK, filter2); - target2.setRequired(true); - while (cards.size() > 1) { - player.choose(Outcome.Detriment, cards, target2, game); - Card card = cards.get(target2.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); - } - target2.clearChosen(); - } - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - if (card != null) { - card.moveToZone(Zone.LIBRARY, source.getId(), game, true); - } - } - return true; - } - - @Override - public HalimarDepthsEffect copy() { - return new HalimarDepthsEffect(this); - } - -} diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java index 65e6a92a0fe..e7ff33ef2d8 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java @@ -28,15 +28,21 @@ package mage.abilities.effects.common; +import mage.Constants; import mage.Constants.Outcome; import mage.Constants.Zone; import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; 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; /** * @@ -44,45 +50,120 @@ import mage.players.Player; */ public class LookLibraryControllerEffect extends OneShotEffect { + private int numberOfCards; + private boolean mayShuffleAfter; + public LookLibraryControllerEffect() { + this(1); + } + + public LookLibraryControllerEffect(int numberOfCards) { + this(numberOfCards, false); + } + + public LookLibraryControllerEffect(int numberOfCards, boolean mayShuffleAfter) { super(Outcome.Benefit); - staticText = "Look at the top card of your Library"; + this.numberOfCards = numberOfCards; + this.mayShuffleAfter = mayShuffleAfter; } public LookLibraryControllerEffect(final LookLibraryControllerEffect effect) { super(effect); + this.numberOfCards = effect.numberOfCards; + this.mayShuffleAfter = effect.mayShuffleAfter; } @Override public LookLibraryControllerEffect copy() { return new LookLibraryControllerEffect(this); + } @Override public boolean apply(Game game, Ability source) { - String windowname; - Player player = game.getPlayer(source.getControllerId()); - Card sourcecard = game.getCard(source.getSourceId()); - if (sourcecard == null) { - windowname = "Top card"; + String windowName ="Reveal"; + if (source instanceof SpellAbility) { + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard != null) + windowName = sourceCard.getName(); } else { - windowname = sourcecard.getName(); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent != null) + windowName = sourcePermanent.getName(); } + + Player player = game.getPlayer(source.getControllerId()); if (player == null) { return false; } - Card card = player.getLibrary().getFromTop(game); - if (card != null) { - Cards cards = new CardsImpl(Zone.PICK); - cards.add(card); - player.lookAtCards(windowname, cards, game); - } else { - return false; + Cards cards = new CardsImpl(Zone.PICK); + int count = Math.min(player.getLibrary().size(), this.numberOfCards); + for (int i = 0; i < count; i++) { + Card card = player.getLibrary().removeFromTop(game); + if (card != null) { + cards.add(card); + game.setZone(card.getId(), Zone.PICK); + } } + player.lookAtCards(windowName, cards, game); + TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on your library (last chosen will be on top)")); + 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(Zone.LIBRARY, source.getId(), game, true); + } + target.clearChosen(); + } + if (cards.size() == 1) { + Card card = cards.get(cards.iterator().next(), game); + card.moveToZone(Zone.LIBRARY, source.getId(), game, true); + } + if (this.mayShuffleAfter) { + if (player.chooseUse(Constants.Outcome.Benefit, "Shuffle you library?", game)) { + player.shuffleLibrary(game); + } + } return true; } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder("Look at the top "); + switch(this.numberOfCards) { + case 1: + sb.append("card "); + break; + case 2: + sb.append("two"); + break; + case 3: + sb.append("three"); + break; + case 4: + sb.append("four"); + break; + case 5: + sb.append("five"); + break; + default: + sb.append(this.numberOfCards); + break; + } + if (this.numberOfCards > 1) + sb.append(" cards "); + + sb.append("of your Library"); + if (this.numberOfCards > 1) + sb.append(", then put them back in any order"); + if (this.mayShuffleAfter) + sb.append(". You may shuffle your library"); + return sb.toString(); + } } diff --git a/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageEffect.java similarity index 57% rename from Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java rename to Mage/src/mage/abilities/effects/common/PreventAllDamageEffect.java index e6d6582cb96..4239218172a 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageEffect.java @@ -29,10 +29,10 @@ package mage.abilities.effects.common; import mage.Constants.Duration; -import mage.Constants.PhaseStep; import mage.abilities.Ability; +import mage.abilities.Mode; import mage.abilities.effects.PreventionEffectImpl; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.DamageEvent; import mage.game.events.GameEvent; @@ -40,32 +40,38 @@ import mage.game.permanent.Permanent; /** * - * @author BetaSteward_at_googlemail.com + * @author LevelX */ -public class PreventAllCombatDamageEffect extends PreventionEffectImpl { +public class PreventAllDamageEffect extends PreventionEffectImpl { - private FilterCreaturePermanent filter; - - public PreventAllCombatDamageEffect(FilterCreaturePermanent filter, Duration duration) { - super(duration); - this.filter = filter; - staticText = "Prevent all combat damage " + duration.toString() + " dealt by " + filter.getMessage(); - } + private FilterPermanent filter; + private Boolean onlyCombat; - public PreventAllCombatDamageEffect(Duration duration) { - super(duration); - staticText = "Prevent all combat damage " + duration.toString(); - } + public PreventAllDamageEffect(FilterPermanent filter, Duration duration, Boolean onlyCombat) { + super(duration); + this.filter = filter; + this.onlyCombat = onlyCombat; + } + public PreventAllDamageEffect(Duration duration, Boolean onlyCombat) { + super(duration); + this.onlyCombat = onlyCombat; + } - public PreventAllCombatDamageEffect(final PreventAllCombatDamageEffect effect) { - super(effect); - if (effect.filter != null) - this.filter = effect.filter.copy(); - } + public PreventAllDamageEffect(Duration duration) { + super(duration); + this.onlyCombat = false; + } + + public PreventAllDamageEffect(final PreventAllDamageEffect effect) { + super(effect); + if (effect.filter != null) + this.filter = effect.filter.copy(); + this.onlyCombat = effect.onlyCombat; + } @Override - public PreventAllCombatDamageEffect copy() { - return new PreventAllCombatDamageEffect(this); + public PreventAllDamageEffect copy() { + return new PreventAllDamageEffect(this); } @Override @@ -78,8 +84,15 @@ public class PreventAllCombatDamageEffect extends PreventionEffectImpl { + + private ObjectColor setColor; + + public SetCardColorTargetEffect(ObjectColor setColor, Constants.Duration duration, String text) { + super(duration, Constants.Layer.ColorChangingEffects_5, Constants.SubLayer.NA, Constants.Outcome.Benefit); + this.setColor = setColor; + staticText = text; + } + + public SetCardColorTargetEffect(ObjectColor setColor, Constants.Duration duration) { + super(duration, Constants.Layer.ColorChangingEffects_5, Constants.SubLayer.NA, Constants.Outcome.Benefit); + this.setColor = setColor; + } + + public SetCardColorTargetEffect(final SetCardColorTargetEffect effect) { + super(effect); + this.setColor = effect.setColor; + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject o = game.getObject(source.getTargets().getFirstTarget()); + if (o != null) { + if (o instanceof Permanent || o instanceof StackObject) + o.getColor().setColor(setColor); + } + +// Permanent target = game.getCard(id)Permanent(); +// if (target != null) { +// if (target != null) { +// target.getColor().setColor(setColor); +// return true; +// } +// } + return false; + } + + @Override + public SetCardColorTargetEffect copy() { + return new SetCardColorTargetEffect(this); + } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder(); + sb.append("Target ").append(mode.getTargets().get(0).getTargetName()); + sb.append(" becomes ").append(setColor.getDescription()); + sb.append(" ").append(duration.toString()); + return sb.toString(); + } +} \ No newline at end of file diff --git a/Mage/src/mage/counters/CounterType.java b/Mage/src/mage/counters/CounterType.java index c765ceea9ad..91ff51e2ae2 100644 --- a/Mage/src/mage/counters/CounterType.java +++ b/Mage/src/mage/counters/CounterType.java @@ -49,11 +49,12 @@ public enum CounterType { FEATHER(new FeatherCounter().name), QUEST(new QuestCounter().name), ARROWHEAD(new ArrowheadCounter().name), + AIM(new AimCounter().name), EON(new EonCounter().name), - AWAKENING(new AwakeningCounter().name), + AWAKENING(new AwakeningCounter().name), DEVOTION(new DevotionCounter().name), DIVINITY(new DivinityCounter().name), - WISH(new WishCounter().name), + WISH(new WishCounter().name), HOOFPRINT(new HoofprintCounter().name), HATCHLING(new HatchlingCounter().name), KI(new KiCounter().name), @@ -119,6 +120,8 @@ public enum CounterType { return new QuestCounter(amount); case ARROWHEAD: return new ArrowheadCounter(amount); + case AIM: + return new AimCounter(amount); case EON: return new EonCounter(amount); case AWAKENING: diff --git a/Mage/src/mage/counters/common/AimCounter.java b/Mage/src/mage/counters/common/AimCounter.java new file mode 100644 index 00000000000..0cb59fcb1c6 --- /dev/null +++ b/Mage/src/mage/counters/common/AimCounter.java @@ -0,0 +1,55 @@ +/* +* 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.counters.common; + +import mage.counters.Counter; + +/** + * Arrowhead counter. + * + * @author LevelX + */ +public class AimCounter extends Counter { + + public AimCounter() { + super("aim"); + this.count = 1; + } + + public AimCounter(int amount) { + super("aim"); + this.count = amount; + } + +// public AimCounter(DynamicValue amountDynamicValue) { +// super("aim"); +// this.count = StaticValue(amountDynamicValue); +// } + +} diff --git a/Mage/src/mage/filter/common/FilterSpellOrPermanent.java b/Mage/src/mage/filter/common/FilterSpellOrPermanent.java new file mode 100644 index 00000000000..450b631e02b --- /dev/null +++ b/Mage/src/mage/filter/common/FilterSpellOrPermanent.java @@ -0,0 +1,107 @@ +/* + * + * 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.filter.common; + +import java.util.UUID; +import mage.filter.FilterImpl; +import mage.filter.FilterInPlay; +import mage.filter.FilterPermanent; +import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; + +/** + * + * @author LevelX + */ +public class FilterSpellOrPermanent extends FilterImpl implements FilterInPlay { + + protected FilterPermanent permanentFilter; + protected FilterSpell spellFilter; + + public FilterSpellOrPermanent() { + this("spell or permanent"); + } + + public FilterSpellOrPermanent(String name, UUID controllerId) { + super(name); + permanentFilter = new FilterPermanent(); + spellFilter = new FilterSpell(); + permanentFilter.getControllerId().add(controllerId); + spellFilter.getControllerId().add(controllerId); + } + + public FilterSpellOrPermanent(String name) { + super(name); + permanentFilter = new FilterPermanent(); + spellFilter = new FilterSpell(); + } + + public FilterSpellOrPermanent(final FilterSpellOrPermanent filter) { + super(filter); + this.permanentFilter = filter.permanentFilter.copy(); + this.spellFilter = filter.spellFilter.copy(); + } + + @Override + public boolean match(Object o) { + if (o instanceof Spell) { + return spellFilter.match((Spell) o); + } else if (o instanceof Permanent) { + return permanentFilter.match((Permanent) o); + } + return notFilter; + } + + @Override + public boolean match(Object o, UUID sourceId, UUID playerId, Game game) { + if (o instanceof Spell) { + return spellFilter.match((Spell) o, playerId, game); + } else if (o instanceof Permanent) { + return permanentFilter.match((Permanent) o, sourceId, playerId, game); + } + return notFilter; + } + + public FilterPermanent getPermanentFilter() { + return this.permanentFilter; + } + + public FilterSpell getspellFilter() { + return this.spellFilter; + } + + @Override + public FilterSpellOrPermanent copy() { + return new FilterSpellOrPermanent(this); + } + +} diff --git a/Mage/src/mage/target/common/TargetSpellOrPermanent.java b/Mage/src/mage/target/common/TargetSpellOrPermanent.java new file mode 100644 index 00000000000..7d47856ac50 --- /dev/null +++ b/Mage/src/mage/target/common/TargetSpellOrPermanent.java @@ -0,0 +1,242 @@ +/* + * + * 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.target.common; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.Constants.Zone; +import mage.MageObject; +import mage.abilities.Ability; +import mage.filter.Filter; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterSpellOrPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.target.TargetImpl; + +/** + * + * @author LevelX + */ +public class TargetSpellOrPermanent extends TargetImpl { + + protected FilterSpellOrPermanent filter; + protected FilterPermanent filterPermanent; + + public TargetSpellOrPermanent() { + this(1, 1); + } + + public TargetSpellOrPermanent(int numTargets) { + this(numTargets, numTargets); + } + + public TargetSpellOrPermanent(int minNumTargets, int maxNumTargets) { + this.minNumberOfTargets = minNumTargets; + this.maxNumberOfTargets = maxNumTargets; + this.zone = Zone.ALL; + this.filter = new FilterSpellOrPermanent(); + this.targetName = filter.getMessage(); + this.filterPermanent = new FilterPermanent(); + } + + public TargetSpellOrPermanent(int minNumTargets, int maxNumTargets, boolean notTarget) { + this(minNumTargets, maxNumTargets); + this.notTarget = notTarget; + } + + public TargetSpellOrPermanent(int minNumTargets, int maxNumTargets, FilterSpellOrPermanent filter,boolean notTarget) { + this(minNumTargets, maxNumTargets); + this.notTarget = notTarget; + this.filter = filter; + } + public TargetSpellOrPermanent(final TargetSpellOrPermanent target) { + super(target); + this.filter = target.filter.copy(); + } + + @Override + public Filter getFilter() { + return this.filter; + } + + public void setFilter(FilterSpellOrPermanent filter) { + this.filter = filter; + } + + @Override + public boolean canTarget(UUID id, Game game) { + Permanent permanent = game.getPermanent(id); + if (permanent != null) { + return filter.match(permanent); + } + Spell spell = game.getStack().getSpell(id); + if (spell != null) + return filter.match(spell); + return false; + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + Permanent permanent = game.getPermanent(id); + MageObject targetSource = game.getObject(source.getSourceId()); + if (permanent != null) { + if (source != null) + return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + else + return filter.match(permanent); + } + Spell spell = game.getStack().getSpell(id); + if (spell != null) + return filter.match(spell); + return false; + } + + /** + * Checks if there are enough {@link mage.game.permanent.Permanent} or {@link mage.game.stack.Spell} that can be chosen. Should only be used + * for Ability targets since this checks for protection, shroud etc. + * + * @param sourceId - the target event source + * @param sourceControllerId - controller of the target event source + * @param game + * @return - true if enough valid {@link mage.game.permanent.Permanent} or {@link mage.game.stack.Spell} exist + */ + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + int count = 0; + MageObject targetSource = game.getObject(sourceId); + for (StackObject stackObject: game.getStack()) { + Spell spell = game.getStack().getSpell(stackObject.getId()); + if (spell != null && filter.match(spell, sourceId, sourceControllerId, game)) { + count++; + if (count >= this.minNumberOfTargets) + return true; + } + } + for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { + count++; + if (count >= this.minNumberOfTargets) + return true; + } + } + return false; + } + + /** + * Checks if there are enough {@link mage.game.permanent.Permanent} or {@link mage.game.stack.Spell} that can be selected. Should not be used + * for Ability targets since this does not check for protection, shroud etc. + * + * @param sourceControllerId - controller of the select event + * @param game + * @return - true if enough valid {@link mage.game.permanent.Permanent} or {@link mage.game.stack.Spell} exist + */ + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + int count = 0; + for (StackObject stackObject: game.getStack()) { + Spell spell = game.getStack().getSpell(stackObject.getId()); + if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell)) { + count++; + if (count >= this.minNumberOfTargets) + return true; + } + } + for (Permanent permanent: game.getBattlefield().getActivePermanents(filterPermanent, sourceControllerId, game)) { + if (filter.match(permanent, null, sourceControllerId, game) && filter.match(permanent)) { + count++; + if (count >= this.minNumberOfTargets) + return true; + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet(); + MageObject targetSource = game.getObject(sourceId); + for (StackObject stackObject: game.getStack()) { + Spell spell = game.getStack().getSpell(stackObject.getId()); + if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell)) { + possibleTargets.add(spell.getId()); + } + } + for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) { + possibleTargets.add(permanent.getId()); + } + } + return possibleTargets; + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet(); + for (StackObject stackObject: game.getStack()) { + Spell spell = game.getStack().getSpell(stackObject.getId()); + if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell)) { + possibleTargets.add(spell.getId()); + } + } + for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) { + if (filter.match(permanent, null, sourceControllerId, game)) { + possibleTargets.add(permanent.getId()); + } + } + return possibleTargets; + } + + @Override + public String getTargetedName(Game game) { + StringBuilder sb = new StringBuilder(); + for (UUID targetId: getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + sb.append(permanent.getName()).append(" "); + } + else { + Spell spell = game.getStack().getSpell(targetId); + sb.append(spell.getName()).append(" "); + } + } + return sb.toString(); + } + + @Override + public TargetSpellOrPermanent copy() { + return new TargetSpellOrPermanent(this); + } + +}