diff --git a/Mage.Sets/src/mage/cards/a/AntiMagicAura.java b/Mage.Sets/src/mage/cards/a/AntiMagicAura.java new file mode 100644 index 0000000000..5f34f7abf4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AntiMagicAura.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CantBeTargetedAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author MTGfan & L_J + */ +public class AntiMagicAura extends CardImpl { + + public AntiMagicAura(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature can't be the target of spells and can't be enchanted by other Auras. + CantBeTargetedAttachedEffect cantTargetEffect = new CantBeTargetedAttachedEffect(new FilterSpell("spells"), Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.ANY); + Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, cantTargetEffect); + ability2.addEffect(new AntiMagicAuraRuleEffect()); + this.addAbility(ability2); + } + + public AntiMagicAura(final AntiMagicAura card) { + super(card); + } + + @Override + public AntiMagicAura copy() { + return new AntiMagicAura(this); + } +} + +// 9/25/2006 ruling: If Consecrate Land enters the battlefield attached to a land that’s enchanted by other Auras, those Auras are put into their owners’ graveyards. +class AntiMagicAuraRuleEffect extends ContinuousRuleModifyingEffectImpl { + + public AntiMagicAuraRuleEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "and can't be enchanted by other Auras"; + } + + public AntiMagicAuraRuleEffect(final AntiMagicAuraRuleEffect effect) { + super(effect); + } + + @Override + public AntiMagicAuraRuleEffect copy() { + return new AntiMagicAuraRuleEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.ATTACH || event.getType() == EventType.STAY_ATTACHED; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent sourceObject = game.getPermanent(source.getSourceId()); + if (sourceObject != null && sourceObject.getAttachedTo() != null) { + if (event.getTargetId().equals(sourceObject.getAttachedTo())) { + return !event.getSourceId().equals(source.getSourceId()); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/ClockworkSteed.java b/Mage.Sets/src/mage/cards/c/ClockworkSteed.java new file mode 100644 index 0000000000..041672cd70 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ClockworkSteed.java @@ -0,0 +1,140 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.condition.common.AttackedOrBlockedThisCombatSourceCondition; +import mage.abilities.condition.common.IsStepCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.counters.Counters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; + +/** + * + * @author escplan9, MarcoMarin & L_J + */ +public class ClockworkSteed extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creatures"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public ClockworkSteed(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.subtype.add(SubType.HORSE); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // Clockwork Steed enters the battlefield with four +1/+0 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P0.createInstance(4)), "with four +1/+0 counters on it")); + + // Clockwork Steed can't be blocked by artifact creatures. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + + // At end of combat, if Clockwork Steed attacked or blocked this combat, remove a +1/+0 counter from it. + this.addAbility(new ConditionalTriggeredAbility( + new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false), + AttackedOrBlockedThisCombatSourceCondition.instance, + "At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."), + new AttackedOrBlockedThisCombatWatcher() + ); + + // {X}, {tap}: Put up to X +1/+0 counters on Clockwork Steed. This ability can't cause the total number of +1/+0 counters on Clockwork Steed to be greater than four. Activate this ability only during your upkeep. + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, + new ClockworkSteedAddCountersSourceEffect( + CounterType.P1P0.createInstance(), + new ManacostVariableValue(), + true, true + ), + new ManaCostsImpl("{X}"), + new IsStepCondition(PhaseStep.UPKEEP), + null + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public ClockworkSteed(final ClockworkSteed card) { + super(card); + } + + @Override + public ClockworkSteed copy() { + return new ClockworkSteed(this); + } +} + +class ClockworkSteedAddCountersSourceEffect extends AddCountersSourceEffect { + + public ClockworkSteedAddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers, boolean putOnCard) { + super(counter, amount, informPlayers, putOnCard); + staticText = "Put up to X +1/+0 counters on {this}. This ability can't cause the total number of +1/+0 counters on {this} to be greater than four."; + } + + @Override + public boolean apply(Game game, Ability source) { + //record how many counters + Counters permCounters = game.getPermanent(source.getSourceId()).getCounters(game); + int countersWas = permCounters.getCount(CounterType.P1P0); + if (countersWas < 4) { + super.apply(game, source); + if (permCounters.getCount(CounterType.P1P0) > 4) { + permCounters.removeCounter(CounterType.P1P0, permCounters.getCount(CounterType.P1P0) - 4); + }//if countersWas < 4 then counter is min(current,4); there is no setCounters function tho + }//else this is a rare case of a Steed getting boosted by outside sources :) Which is the sole purpose of this if, for the benefit of this rare but not impossible case :p + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/d/DrainPower.java b/Mage.Sets/src/mage/cards/d/DrainPower.java index 5cc297b22c..8e81cc943c 100644 --- a/Mage.Sets/src/mage/cards/d/DrainPower.java +++ b/Mage.Sets/src/mage/cards/d/DrainPower.java @@ -100,10 +100,11 @@ class DrainPowerEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(source.getFirstTarget()); if (targetPlayer != null) { List ignorePermanents = new ArrayList<>(); + Map> manaAbilitiesMap = new HashMap<>(); TargetPermanent target = null; - + while (true) { - Map> manaAbilitiesMap = new HashMap<>(); + manaAbilitiesMap.clear(); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) { if (!ignorePermanents.contains(permanent)) { List manaAbilities = new ArrayList<>(); @@ -111,7 +112,6 @@ class DrainPowerEffect extends OneShotEffect { for (Ability ability : permanent.getAbilities()) { if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) { ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability; - // TODO: make Rhystic Cave untappable due to its instant speed limitation (this is a Rhystic Cave canActivate bug) if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game)) { // canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc) // so it's necessary to filter them out manually - might be buggy in some fringe cases @@ -168,7 +168,6 @@ class DrainPowerEffect extends OneShotEffect { // 106.12. One card (Drain Power) causes one player to lose unspent mana and another to add “the mana lost this way.” (Note that these may be the same player.) // This empties the former player’s mana pool and causes the mana emptied this way to be put into the latter player’s mana pool. Which permanents, spells, and/or // abilities produced that mana are unchanged, as are any restrictions or additional effects associated with any of that mana. - // TODO: retain riders associated with drained mana List manaItems = targetPlayer.getManaPool().getManaItems(); targetPlayer.getManaPool().emptyPool(game); for (ManaPoolItem manaPoolItem : manaItems) { diff --git a/Mage.Sets/src/mage/cards/f/FuneralMarch.java b/Mage.Sets/src/mage/cards/f/FuneralMarch.java new file mode 100644 index 0000000000..0a772799c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FuneralMarch.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ZoneChangeTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class FuneralMarch extends CardImpl { + + public FuneralMarch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}{B}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When enchanted creature leaves the battlefield, its controller sacrifices a creature. + this.addAbility(new FuneralMarchTriggeredAbility()); + } + + public FuneralMarch(final FuneralMarch card) { + super(card); + } + + @Override + public FuneralMarch copy() { + return new FuneralMarch(this); + } +} + +class FuneralMarchTriggeredAbility extends ZoneChangeTriggeredAbility { + + public FuneralMarchTriggeredAbility() { + super(Zone.BATTLEFIELD, null, new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "its controller"), "When enchanted creature leaves the battlefield, ", false); + } + + public FuneralMarchTriggeredAbility(final FuneralMarchTriggeredAbility ability) { + super(ability); + } + + @Override + public FuneralMarchTriggeredAbility copy() { + return new FuneralMarchTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent enchantment = game.getPermanentOrLKIBattlefield(this.getSourceId()); + if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if ((fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone)) { + for (Effect effect : getEffects()) { + if (zEvent.getTarget() != null) { + Permanent attachedTo = (Permanent) game.getLastKnownInformation(enchantment.getAttachedTo(), Zone.BATTLEFIELD, enchantment.getAttachedToZoneChangeCounter()); + if (attachedTo != null) { + effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId())); + } + } + } + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GreaterWerewolf.java b/Mage.Sets/src/mage/cards/g/GreaterWerewolf.java new file mode 100644 index 0000000000..72268af829 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GreaterWerewolf.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.counters.BoostCounter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.BlockedByIdPredicate; +import mage.filter.predicate.permanent.BlockingAttackerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class GreaterWerewolf extends CardImpl { + + public GreaterWerewolf(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.subtype.add(SubType.WEREWOLF); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // At end of combat, put a -0/-2 counter on each creature blocking or blocked by Greater Werewolf. + this.addAbility(new EndOfCombatTriggeredAbility(new GreaterWerewolfEffect(), false)); + } + + public GreaterWerewolf(final GreaterWerewolf card) { + super(card); + } + + @Override + public GreaterWerewolf copy() { + return new GreaterWerewolf(this); + } +} + +class GreaterWerewolfEffect extends OneShotEffect { + + public GreaterWerewolfEffect() { + super(Outcome.Detriment); + this.staticText = "put a -0/-2 counter on each creature blocking or blocked by {this}"; + } + + public GreaterWerewolfEffect(final GreaterWerewolfEffect effect) { + super(effect); + } + + @Override + public GreaterWerewolfEffect copy() { + return new GreaterWerewolfEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(Predicates.or(new BlockedByIdPredicate(sourcePermanent.getId()), new BlockingAttackerIdPredicate(sourcePermanent.getId()))); + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { + Effect effect = new AddCountersTargetEffect(new BoostCounter(0, -2), Outcome.UnboostCreature); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + effect.apply(game, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/i/IronclawCurse.java b/Mage.Sets/src/mage/cards/i/IronclawCurse.java new file mode 100644 index 0000000000..aae4e3ff4e --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IronclawCurse.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.cards.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.CantBlockAttachedEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public class IronclawCurse extends CardImpl { + + public IronclawCurse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets 0/-1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0, -1, Duration.WhileOnBattlefield))); + + // Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IronclawCurseEffect())); + } + + public IronclawCurse(final IronclawCurse card) { + super(card); + } + + @Override + public IronclawCurse copy() { + return new IronclawCurse(this); + } +} + +class IronclawCurseEffect extends CantBlockAttachedEffect { + + public IronclawCurseEffect() { + super(AttachmentType.AURA); + this.staticText = "Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness"; + } + + public IronclawCurseEffect(final IronclawCurseEffect effect) { + super(effect); + } + + @Override + public IronclawCurseEffect copy() { + return new IronclawCurseEffect(this); + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); + if (enchantment != null && enchantment.getAttachedTo() != null) { + return !(attacker.getPower().getValue() >= enchantedCreature.getToughness().getValue()); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/r/RelicBind.java b/Mage.Sets/src/mage/cards/r/RelicBind.java new file mode 100644 index 0000000000..74e6144570 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RelicBind.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.BecomesTappedAttachedTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; + +/** + * + * @author L_J + */ +public class RelicBind extends CardImpl { + + private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public RelicBind(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + this.subtype.add(SubType.AURA); + + // Enchant artifact an opponent controls + TargetPermanent auraTarget = new TargetPermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Whenever enchanted artifact becomes tapped, choose one + // — Relic Bind deals 1 damage to target player. + Ability ability2 = new BecomesTappedAttachedTriggeredAbility(new DamageTargetEffect(1), "enchanted artifact"); + ability2.addTarget(new TargetPlayer()); + // — Target player gains 1 life. + Mode mode = new Mode(); + mode.getEffects().add(new GainLifeTargetEffect(1)); + mode.getTargets().add(new TargetPlayer()); + ability2.addMode(mode); + + this.addAbility(ability2); + } + + public RelicBind(final RelicBind card) { + super(card); + } + + @Override + public RelicBind copy() { + return new RelicBind(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SerraBestiary.java b/Mage.Sets/src/mage/cards/s/SerraBestiary.java new file mode 100644 index 0000000000..7129562326 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SerraBestiary.java @@ -0,0 +1,145 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.Optional; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J (based on jeffwadsworth) + */ +public class SerraBestiary extends CardImpl { + + public SerraBestiary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Removal)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, sacrifice Serra Bestiary unless you pay {W}{W}. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{W}{W}")), TargetController.YOU, false)); + + // Enchanted creature can't attack or block, and its activated abilities with {T} in their costs can't be activated. + Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAttachedEffect(AttachmentType.AURA)); + ability2.addEffect(new SerraBestiaryRuleModifyingEffect()); + this.addAbility(ability2); + + } + + public SerraBestiary(final SerraBestiary card) { + super(card); + } + + @Override + public SerraBestiary copy() { + return new SerraBestiary(this); + } +} + +class SerraBestiaryRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { + + public SerraBestiaryRuleModifyingEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = ", and its activated abilities with {T} in their costs can't be activated"; + } + + public SerraBestiaryRuleModifyingEffect(final SerraBestiaryRuleModifyingEffect effect) { + super(effect); + } + + @Override + public SerraBestiaryRuleModifyingEffect copy() { + return new SerraBestiaryRuleModifyingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); + if (enchantment != null && enchantment.getAttachedTo() != null) { + MageObject object = game.getObject(event.getSourceId()); + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() + && object != null + && object.isCreature() + && object.getId().equals(enchantedCreature.getId()) + && game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId())) { + if (ability.get().getCosts().stream().anyMatch((cost) -> (cost instanceof TapSourceCost))) { + return true; + } + } + } + return false; + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + return "Enchanted creature can't use its activated abilities that use {tap} in their costs."; + } +} diff --git a/Mage.Sets/src/mage/cards/v/VenomousBreath.java b/Mage.Sets/src/mage/cards/v/VenomousBreath.java new file mode 100644 index 0000000000..974f2a2829 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VenomousBreath.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.cards.v; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.BlockedAttackerWatcher; + +/** + * + * @author LevelX2 + */ +public class VenomousBreath extends CardImpl { + + public VenomousBreath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}"); + + // Choose target creature. At this turn's next end of combat, destroy all creatures that blocked or were blocked by it this turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new InfoEffect("Choose target creature")); + this.getSpellAbility().addEffect(new VenomousBreathCreateDelayedTriggeredAbilityEffect()); + this.getSpellAbility().addWatcher(new BlockedAttackerWatcher()); + } + + public VenomousBreath(final VenomousBreath card) { + super(card); + } + + @Override + public VenomousBreath copy() { + return new VenomousBreath(this); + } +} + +class VenomousBreathCreateDelayedTriggeredAbilityEffect extends OneShotEffect { + + public VenomousBreathCreateDelayedTriggeredAbilityEffect() { + super(Outcome.Benefit); + this.staticText = "At this turn's next end of combat, destroy all creatures that blocked or were blocked by it this turn"; + } + + public VenomousBreathCreateDelayedTriggeredAbilityEffect(final VenomousBreathCreateDelayedTriggeredAbilityEffect effect) { + super(effect); + } + + @Override + public VenomousBreathCreateDelayedTriggeredAbilityEffect copy() { + return new VenomousBreathCreateDelayedTriggeredAbilityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!source.getTargets().isEmpty() && source.getFirstTarget() != null) { + MageObjectReference mor = new MageObjectReference(source.getFirstTarget(), game); + AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new VenomousBreathEffect(mor)); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } + return false; + } +} + +class VenomousBreathEffect extends OneShotEffect { + + MageObjectReference targetCreature; + + public VenomousBreathEffect(MageObjectReference targetCreature) { + super(Outcome.DestroyPermanent); + this.targetCreature = targetCreature; + } + + public VenomousBreathEffect(final VenomousBreathEffect effect) { + super(effect); + targetCreature = effect.targetCreature; + } + + @Override + public VenomousBreathEffect copy() { + return new VenomousBreathEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && targetCreature != null) { + BlockedAttackerWatcher watcher = (BlockedAttackerWatcher) game.getState().getWatchers().get(BlockedAttackerWatcher.class.getSimpleName()); + if (watcher != null) { + List toDestroy = new ArrayList<>(); + for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) { + if (!creature.getId().equals(targetCreature.getSourceId())) { + if (watcher.creatureHasBlockedAttacker(new MageObjectReference(creature, game), targetCreature, game) || watcher.creatureHasBlockedAttacker(targetCreature, new MageObjectReference(creature, game), game)) { + toDestroy.add(creature); + } + } + } + for (Permanent creature : toDestroy) { + creature.destroy(source.getSourceId(), game, false); + } + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/v/Visions.java b/Mage.Sets/src/mage/cards/v/Visions.java new file mode 100644 index 0000000000..5282ae3c7d --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/Visions.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.effects.common.LookLibraryTopCardTargetPlayerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author L_J + */ +public class Visions extends CardImpl { + + public Visions(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + + // Look at the top five cards of target player's library. You may then have that player shuffle that library. + this.getSpellAbility().addEffect(new LookLibraryTopCardTargetPlayerEffect(5, false, true)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public Visions(final Visions card) { + super(card); + } + + @Override + public Visions copy() { + return new Visions(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WallOfDust.java b/Mage.Sets/src/mage/cards/w/WallOfDust.java new file mode 100644 index 0000000000..d6126143dc --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WallOfDust.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.TurnPhase; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J (based on LevelX2) + */ +public class WallOfDust extends CardImpl { + + public WallOfDust(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.subtype.add(SubType.WALL); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // Whenever Wall of Dust blocks a creature, that creature can't attack during its controller's next turn. + this.addAbility(new BlocksTriggeredAbility(new WallOfDustRestrictionEffect(), false, true)); + } + + public WallOfDust(final WallOfDust card) { + super(card); + } + + @Override + public WallOfDust copy() { + return new WallOfDust(this); + } +} + +class WallOfDustRestrictionEffect extends RestrictionEffect { + + int nextTurnTargetController = 0; + protected MageObjectReference targetPermanentReference; + + public WallOfDustRestrictionEffect() { + super(Duration.Custom); + staticText = "that creature can't attack during its controller's next turn"; + } + + public WallOfDustRestrictionEffect(final WallOfDustRestrictionEffect effect) { + super(effect); + this.nextTurnTargetController = effect.nextTurnTargetController; + this.targetPermanentReference = effect.targetPermanentReference; + } + + @Override + public WallOfDustRestrictionEffect copy() { + return new WallOfDustRestrictionEffect(this); + } + + @Override + public boolean isInactive(Ability source, Game game) { + if (targetPermanentReference == null) { + return true; + } + Permanent targetPermanent = targetPermanentReference.getPermanent(game); + if (targetPermanent == null) { + return true; + } + if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(targetPermanent.getControllerId())) { + nextTurnTargetController = game.getTurnNum(); + } + return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController; + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (getTargetPointer().getFirst(game, source) == null) { + discard(); + } else { + targetPermanentReference = new MageObjectReference(getTargetPointer().getFirst(game, source), game); + } + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + if (permanent.getId().equals(getTargetPointer().getFirst(game, source))) { + if (game.getActivePlayerId().equals(permanent.getControllerId())) { + return true; + } + } + return false; + } + + public boolean canAttack(Game game) { + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index 520dc1c6de..fa31ca8cbf 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -43,6 +43,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Ambush Party", 208, Rarity.COMMON, mage.cards.a.AmbushParty.class)); cards.add(new SetCardInfo("Amulet of Kroog", 347, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); cards.add(new SetCardInfo("An-Havva Constable", 139, Rarity.RARE, mage.cards.a.AnHavvaConstable.class)); + cards.add(new SetCardInfo("Anti-Magic Aura", 72, Rarity.UNCOMMON, mage.cards.a.AntiMagicAura.class)); cards.add(new SetCardInfo("Angry Mob", 280, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); cards.add(new SetCardInfo("Animate Dead", 2, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class)); cards.add(new SetCardInfo("Animate Wall", 281, Rarity.RARE, mage.cards.a.AnimateWall.class)); @@ -101,6 +102,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("City of Brass", 413, Rarity.RARE, mage.cards.c.CityOfBrass.class)); cards.add(new SetCardInfo("Clay Statue", 355, Rarity.COMMON, mage.cards.c.ClayStatue.class)); cards.add(new SetCardInfo("Clockwork Beast", 356, Rarity.RARE, mage.cards.c.ClockworkBeast.class)); + cards.add(new SetCardInfo("Clockwork Steed", 257, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class)); cards.add(new SetCardInfo("Cockatrice", 146, Rarity.RARE, mage.cards.c.Cockatrice.class)); cards.add(new SetCardInfo("Colossus of Sardia", 358, Rarity.RARE, mage.cards.c.ColossusOfSardia.class)); cards.add(new SetCardInfo("Conquer", 216, Rarity.UNCOMMON, mage.cards.c.Conquer.class)); @@ -185,6 +187,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Foxfire", 157, Rarity.COMMON, mage.cards.f.Foxfire.class)); cards.add(new SetCardInfo("Fountain of Youth", 372, Rarity.UNCOMMON, mage.cards.f.FountainOfYouth.class)); cards.add(new SetCardInfo("Frozen Shade", 25, Rarity.COMMON, mage.cards.f.FrozenShade.class)); + cards.add(new SetCardInfo("Funeral March", 26, Rarity.COMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Fungusaur", 158, Rarity.RARE, mage.cards.f.Fungusaur.class)); cards.add(new SetCardInfo("Fyndhorn Elder", 159, Rarity.UNCOMMON, mage.cards.f.FyndhornElder.class)); cards.add(new SetCardInfo("Game of Chaos", 232, Rarity.RARE, mage.cards.g.GameOfChaos.class)); @@ -203,6 +206,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Goblin Warrens", 238, Rarity.RARE, mage.cards.g.GoblinWarrens.class)); cards.add(new SetCardInfo("Grapeshot Catapult", 375, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); cards.add(new SetCardInfo("Greater Realm of Preservation", 307, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class)); + cards.add(new SetCardInfo("Greater Werewolf", 28, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class)); cards.add(new SetCardInfo("Grizzly Bears", 163, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); cards.add(new SetCardInfo("Havenwood Battleground", 421, Rarity.UNCOMMON, mage.cards.h.HavenwoodBattleground.class)); cards.add(new SetCardInfo("Heal", 308, Rarity.COMMON, mage.cards.h.Heal.class)); @@ -231,6 +235,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Infinite Hourglass", 378, Rarity.RARE, mage.cards.i.InfiniteHourglass.class)); cards.add(new SetCardInfo("Initiates of the Ebon Hand", 31, Rarity.COMMON, InitiatesOfTheEbonHand.class)); cards.add(new SetCardInfo("Instill Energy", 166, Rarity.UNCOMMON, mage.cards.i.InstillEnergy.class)); + cards.add(new SetCardInfo("Ironclaw Curse", 244, Rarity.RARE, mage.cards.i.IronclawCurse.class)); cards.add(new SetCardInfo("Ironclaw Orcs", 245, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); cards.add(new SetCardInfo("Ironroot Treefolk", 167, Rarity.COMMON, mage.cards.i.IronrootTreefolk.class)); cards.add(new SetCardInfo("Iron Star", 379, Rarity.UNCOMMON, mage.cards.i.IronStar.class)); @@ -373,6 +378,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Segovian Leviathan", 122, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); cards.add(new SetCardInfo("Sengir Autocrat", 55, Rarity.RARE, mage.cards.s.SengirAutocrat.class)); cards.add(new SetCardInfo("Serpent Generator", 397, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); + cards.add(new SetCardInfo("Serra Bestiary", 336, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class)); cards.add(new SetCardInfo("Serra Paladin", 337, Rarity.UNCOMMON, mage.cards.s.SerraPaladin.class)); cards.add(new SetCardInfo("Shanodin Dryads", 187, Rarity.COMMON, mage.cards.s.ShanodinDryads.class)); cards.add(new SetCardInfo("Shapeshifter", 398, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java index 7405ca25a5..621e2613f8 100644 --- a/Mage.Sets/src/mage/sets/FourthEdition.java +++ b/Mage.Sets/src/mage/sets/FourthEdition.java @@ -148,6 +148,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("Prodigal Sorcerer", 94, Rarity.COMMON, mage.cards.p.ProdigalSorcerer.class)); cards.add(new SetCardInfo("Psionic Entity", 95, Rarity.RARE, mage.cards.p.PsionicEntity.class)); cards.add(new SetCardInfo("Psychic Venom", 96, Rarity.COMMON, mage.cards.p.PsychicVenom.class)); + cards.add(new SetCardInfo("Relic Bind", 97, Rarity.RARE, mage.cards.r.RelicBind.class)); cards.add(new SetCardInfo("Sea Serpent", 98, Rarity.COMMON, mage.cards.s.SeaSerpent.class)); cards.add(new SetCardInfo("Segovian Leviathan", 99, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); cards.add(new SetCardInfo("Sindbad", 100, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); @@ -294,6 +295,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("The Brute", 226, Rarity.COMMON, mage.cards.t.TheBrute.class)); cards.add(new SetCardInfo("Tunnel", 227, Rarity.UNCOMMON, mage.cards.t.Tunnel.class)); cards.add(new SetCardInfo("Uthden Troll", 228, Rarity.UNCOMMON, mage.cards.u.UthdenTroll.class)); + cards.add(new SetCardInfo("Wall of Dust", 229, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); cards.add(new SetCardInfo("Wall of Fire", 230, Rarity.UNCOMMON, mage.cards.w.WallOfFire.class)); cards.add(new SetCardInfo("Wall of Stone", 231, Rarity.UNCOMMON, mage.cards.w.WallOfStone.class)); cards.add(new SetCardInfo("Winds of Change", 232, Rarity.RARE, mage.cards.w.WindsOfChange.class)); @@ -350,6 +352,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("Spirit Link", 51, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); cards.add(new SetCardInfo("Swords to Plowshares", 52, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Tundra Wolves", 53, Rarity.COMMON, mage.cards.t.TundraWolves.class)); + cards.add(new SetCardInfo("Visions", 54, Rarity.UNCOMMON, mage.cards.v.Visions.class)); cards.add(new SetCardInfo("Wall of Swords", 55, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); cards.add(new SetCardInfo("White Knight", 56, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class)); cards.add(new SetCardInfo("White Ward", 57, Rarity.UNCOMMON, mage.cards.w.WhiteWard.class)); diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 36f9053525..7439c7568c 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -103,6 +103,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Chain Stasis", 28, Rarity.RARE, mage.cards.c.ChainStasis.class)); cards.add(new SetCardInfo("Chandler", 88, Rarity.COMMON, mage.cards.c.Chandler.class)); cards.add(new SetCardInfo("Clockwork Gnomes", 127, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class)); + cards.add(new SetCardInfo("Clockwork Steed", 128, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class)); cards.add(new SetCardInfo("Clockwork Swarm", 129, Rarity.COMMON, mage.cards.c.ClockworkSwarm.class)); cards.add(new SetCardInfo("Coral Reef", 29, Rarity.COMMON, mage.cards.c.CoralReef.class)); cards.add(new SetCardInfo("Dark Maze", 30, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS)); @@ -126,14 +127,17 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Folk of An-Havva", 58, Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Folk of An-Havva", 59, Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forget", 32, Rarity.RARE, mage.cards.f.Forget.class)); + cards.add(new SetCardInfo("Funeral March", 11, Rarity.UNCOMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Ghost Hounds", 12, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class)); cards.add(new SetCardInfo("Grandmother Sengir", 13, Rarity.RARE, mage.cards.g.GrandmotherSengir.class)); + cards.add(new SetCardInfo("Greater Werewolf", 14, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class)); cards.add(new SetCardInfo("Hazduhr the Abbot", 110, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class)); cards.add(new SetCardInfo("Headstone", 15, Rarity.COMMON, mage.cards.h.Headstone.class)); cards.add(new SetCardInfo("Hungry Mist", 60, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hungry Mist", 61, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ihsan's Shade", 16, Rarity.UNCOMMON, mage.cards.i.IhsansShade.class)); cards.add(new SetCardInfo("Irini Sengir", 17, Rarity.UNCOMMON, mage.cards.i.IriniSengir.class)); + cards.add(new SetCardInfo("Ironclaw Curse", 96, Rarity.RARE, mage.cards.i.IronclawCurse.class)); cards.add(new SetCardInfo("Jinx", 36, Rarity.COMMON, mage.cards.j.Jinx.class)); cards.add(new SetCardInfo("Joven", 97, Rarity.COMMON, mage.cards.j.Joven.class)); cards.add(new SetCardInfo("Joven's Tools", 133, Rarity.UNCOMMON, mage.cards.j.JovensTools.class)); @@ -166,6 +170,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Sengir Bats", 20, Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sengir Bats", 21, Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Serra Aviary", 118, Rarity.RARE, mage.cards.s.SerraAviary.class)); + cards.add(new SetCardInfo("Serra Bestiary", 119, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class)); cards.add(new SetCardInfo("Serra Paladin", 121, Rarity.COMMON, mage.cards.s.SerraPaladin.class)); cards.add(new SetCardInfo("Serrated Arrows", 135, Rarity.COMMON, mage.cards.s.SerratedArrows.class)); cards.add(new SetCardInfo("Shrink", 70, Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index b25801592b..892a4931b3 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -346,6 +346,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Updraft", 105, Rarity.UNCOMMON, mage.cards.u.Updraft.class)); cards.add(new SetCardInfo("Urza's Bauble", 318, Rarity.UNCOMMON, mage.cards.u.UrzasBauble.class)); cards.add(new SetCardInfo("Veldt", 358, Rarity.RARE, mage.cards.v.Veldt.class)); + cards.add(new SetCardInfo("Venomous Breath", 161, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class)); cards.add(new SetCardInfo("Vertigo", 222, Rarity.UNCOMMON, mage.cards.v.Vertigo.class)); cards.add(new SetCardInfo("Vexing Arcanix", 319, Rarity.RARE, mage.cards.v.VexingArcanix.class)); cards.add(new SetCardInfo("Vibrating Sphere", 320, Rarity.RARE, mage.cards.v.VibratingSphere.class)); diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 3e9ab7b76a..d1b70490de 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -66,6 +66,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Amrou Kithkin", 172, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); cards.add(new SetCardInfo("Angelic Voices", 173, Rarity.RARE, mage.cards.a.AngelicVoices.class)); cards.add(new SetCardInfo("Angus Mackenzie", 257, Rarity.RARE, mage.cards.a.AngusMackenzie.class)); + cards.add(new SetCardInfo("Anti-Magic Aura", 45, Rarity.COMMON, mage.cards.a.AntiMagicAura.class)); cards.add(new SetCardInfo("Arboria", 88, Rarity.UNCOMMON, mage.cards.a.Arboria.class)); cards.add(new SetCardInfo("Arcades Sabboth", 258, Rarity.RARE, mage.cards.a.ArcadesSabboth.class)); cards.add(new SetCardInfo("Arena of the Ancients", 215, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class)); @@ -235,6 +236,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Red Mana Battery", 236, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class)); cards.add(new SetCardInfo("Reincarnation", 115, Rarity.UNCOMMON, mage.cards.r.Reincarnation.class)); cards.add(new SetCardInfo("Relic Barrier", 237, Rarity.UNCOMMON, mage.cards.r.RelicBarrier.class)); + cards.add(new SetCardInfo("Relic Bind", 71, Rarity.UNCOMMON, mage.cards.r.RelicBind.class)); cards.add(new SetCardInfo("Remove Enchantments", 202, Rarity.COMMON, mage.cards.r.RemoveEnchantments.class)); cards.add(new SetCardInfo("Remove Soul", 72, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); cards.add(new SetCardInfo("Reset", 73, Rarity.UNCOMMON, mage.cards.r.Reset.class)); @@ -293,8 +295,10 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Urborg", 255, Rarity.UNCOMMON, mage.cards.u.Urborg.class)); cards.add(new SetCardInfo("Vaevictis Asmadi", 309, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); cards.add(new SetCardInfo("Vampire Bats", 39, Rarity.COMMON, mage.cards.v.VampireBats.class)); + cards.add(new SetCardInfo("Visions", 210, Rarity.UNCOMMON, mage.cards.v.Visions.class)); cards.add(new SetCardInfo("Walking Dead", 40, Rarity.COMMON, mage.cards.w.WalkingDead.class)); cards.add(new SetCardInfo("Wall of Caltrops", 211, Rarity.COMMON, mage.cards.w.WallOfCaltrops.class)); + cards.add(new SetCardInfo("Wall of Dust", 165, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); cards.add(new SetCardInfo("Wall of Earth", 166, Rarity.COMMON, mage.cards.w.WallOfEarth.class)); cards.add(new SetCardInfo("Wall of Heat", 167, Rarity.COMMON, mage.cards.w.WallOfHeat.class)); cards.add(new SetCardInfo("Wall of Light", 212, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 6d1617f363..bf8ed96024 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -98,6 +98,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Burnout", 121, Rarity.UNCOMMON, mage.cards.b.Burnout.class)); cards.add(new SetCardInfo("Carapace", 155, Rarity.COMMON, mage.cards.c.Carapace.class)); cards.add(new SetCardInfo("Caribou Range", 8, Rarity.RARE, mage.cards.c.CaribouRange.class)); + cards.add(new SetCardInfo("Clockwork Steed", 205, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class)); cards.add(new SetCardInfo("Combat Medic", 9, Rarity.COMMON, CombatMedic.class)); cards.add(new SetCardInfo("Conquer", 122, Rarity.UNCOMMON, mage.cards.c.Conquer.class)); cards.add(new SetCardInfo("Counterspell", 44, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); @@ -138,6 +139,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Forgotten Lore", 164, Rarity.UNCOMMON, mage.cards.f.ForgottenLore.class)); cards.add(new SetCardInfo("Foul Familiar", 90, Rarity.COMMON, mage.cards.f.FoulFamiliar.class)); cards.add(new SetCardInfo("Fumarole", 194, Rarity.UNCOMMON, mage.cards.f.Fumarole.class)); + cards.add(new SetCardInfo("Funeral March", 91, Rarity.COMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Fungal Bloom", 165, Rarity.RARE, mage.cards.f.FungalBloom.class)); cards.add(new SetCardInfo("Fyndhorn Pollen", 166, Rarity.RARE, mage.cards.f.FyndhornPollen.class)); cards.add(new SetCardInfo("Gangrenous Zombies", 92, Rarity.COMMON, mage.cards.g.GangrenousZombies.class)); @@ -178,7 +180,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class)); cards.add(new SetCardInfo("Krovikan Horror", 101, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); cards.add(new SetCardInfo("Krovikan Sorcerer", 51, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class)); - cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class)); + cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class)); cards.add(new SetCardInfo("Leaping Lizard", 171, Rarity.COMMON, mage.cards.l.LeapingLizard.class)); cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, LimDulsHighGuard.class)); cards.add(new SetCardInfo("Lodestone Bauble", 213, Rarity.RARE, mage.cards.l.LodestoneBauble.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index d8180dd5a7..41f34f221f 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -254,6 +254,7 @@ public class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Serendib Djinn", 61, Rarity.RARE, mage.cards.s.SerendibDjinn.class)); cards.add(new SetCardInfo("Serra Angel", 25, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); cards.add(new SetCardInfo("Serra Aviary", 26, Rarity.UNCOMMON, mage.cards.s.SerraAviary.class)); + cards.add(new SetCardInfo("Serra Bestiary", 27, Rarity.COMMON, mage.cards.s.SerraBestiary.class)); cards.add(new SetCardInfo("Shapeshifter", 226, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); cards.add(new SetCardInfo("Shivan Dragon", 136, Rarity.RARE, mage.cards.s.ShivanDragon.class)); cards.add(new SetCardInfo("Sinkhole", 97, Rarity.RARE, mage.cards.s.Sinkhole.class)); diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index 5fab43e440..923cc33a4c 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -360,6 +360,7 @@ public class MercadianMasques extends ExpansionSet { cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class)); cards.add(new SetCardInfo("Uphill Battle", 222, Rarity.UNCOMMON, mage.cards.u.UphillBattle.class)); cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class)); + cards.add(new SetCardInfo("Venomous Breath", 281, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class)); cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class)); cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class)); cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java index 3081206ac6..3b10ddb9ba 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java @@ -47,11 +47,13 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { protected int amount; protected boolean putToGraveyard; + protected boolean mayShuffleAfter; // for Visions public LookLibraryTopCardTargetPlayerEffect(int amount) { super(Outcome.Benefit); this.amount = amount; this.putToGraveyard = false; + this.mayShuffleAfter = false; setText(); } @@ -59,6 +61,15 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { super(Outcome.Benefit); this.amount = amount; this.putToGraveyard = putToGraveyard; + this.mayShuffleAfter = false; + setText(); + } + + public LookLibraryTopCardTargetPlayerEffect(int amount, boolean putToGraveyard, boolean mayShuffleAfter) { + super(Outcome.Benefit); + this.amount = amount; + this.putToGraveyard = putToGraveyard; + this.mayShuffleAfter = mayShuffleAfter; setText(); } @@ -70,6 +81,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { super(effect); amount = effect.amount; putToGraveyard = effect.putToGraveyard; + mayShuffleAfter = effect.mayShuffleAfter; } @Override @@ -95,6 +107,11 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { } } } + if (mayShuffleAfter) { + if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle his or her library?"), source, game)) { + targetPlayer.shuffleLibrary(source, game); + } + } return true; } return false; @@ -118,6 +135,9 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { } sb.append(" into that player's graveyard"); } + if (mayShuffleAfter) { + sb.append(". You may then have that player shuffle that library"); + } this.staticText = sb.toString(); } }