From f5b4c4118870d1e318a47005203ee3cd7f8fd3f8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 6 May 2017 16:05:14 +0200 Subject: [PATCH] * Ravnica: City of Guilds - Added 3 cards. --- Mage.Sets/src/mage/cards/q/Quickchange.java | 64 +++++++++++++++++ Mage.Sets/src/mage/cards/r/Reroute.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/cards/z/ZephyrSpirit.java | 64 +++++++++++++++++ .../src/mage/sets/RavnicaCityOfGuilds.java | 3 + .../main/java/mage/filter/FilterAbility.java | 4 ++ .../target/common/TargetActivatedAbility.java | 26 +++++-- 6 files changed, 225 insertions(+), 7 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/q/Quickchange.java create mode 100644 Mage.Sets/src/mage/cards/r/Reroute.java create mode 100644 Mage.Sets/src/mage/cards/z/ZephyrSpirit.java diff --git a/Mage.Sets/src/mage/cards/q/Quickchange.java b/Mage.Sets/src/mage/cards/q/Quickchange.java new file mode 100644 index 00000000000..47ce4239f52 --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/Quickchange.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.cards.q; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BecomesColorOrColorsTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Quickchange extends CardImpl { + + public Quickchange(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Target creature becomes the color or colors of your choice until end of turn. + this.getSpellAbility().addEffect(new BecomesColorOrColorsTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public Quickchange(final Quickchange card) { + super(card); + } + + @Override + public Quickchange copy() { + return new Quickchange(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/Reroute.java b/Mage.Sets/src/mage/cards/r/Reroute.java new file mode 100644 index 00000000000..a4aa46d4b13 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Reroute.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.cards.r; + +import java.util.UUID; +import mage.abilities.effects.common.ChooseNewTargetsTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterAbility; +import mage.filter.predicate.mageobject.NumberOfTargetsPredicate; +import mage.target.common.TargetActivatedAbility; + +/** + * + * @author LevelX2 + */ +public class Reroute extends CardImpl { + + private static final FilterAbility filter = new FilterAbility("activated ability with a single target"); + + static { + filter.add(new NumberOfTargetsPredicate(1)); + } + + public Reroute(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); + + // Change the target of target activated ability with a single target. + this.getSpellAbility().addEffect(new ChooseNewTargetsTargetEffect(true, true)); + this.getSpellAbility().addTarget(new TargetActivatedAbility(filter)); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public Reroute(final Reroute card) { + super(card); + } + + @Override + public Reroute copy() { + return new Reroute(this); + } +} diff --git a/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java b/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java new file mode 100644 index 00000000000..e67e5058eda --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZephyrSpirit.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.cards.z; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author LevelX2 + */ +public class ZephyrSpirit extends CardImpl { + + public ZephyrSpirit(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); + + this.subtype.add("Spirit"); + this.power = new MageInt(0); + this.toughness = new MageInt(6); + + // When Zephyr Spirit blocks, return it to its owner's hand. + this.addAbility(new BlocksTriggeredAbility( + new ReturnToHandSourceEffect(true).setText("return it to its owner's hand"), false)); + } + + public ZephyrSpirit(final ZephyrSpirit card) { + super(card); + } + + @Override + public ZephyrSpirit copy() { + return new ZephyrSpirit(this); + } +} diff --git a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java index 449af3b2240..ae72b23ddf4 100644 --- a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java +++ b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java @@ -247,12 +247,14 @@ public class RavnicaCityOfGuilds extends ExpansionSet { cards.add(new SetCardInfo("Privileged Position", 251, Rarity.RARE, mage.cards.p.PrivilegedPosition.class)); cards.add(new SetCardInfo("Psychic Drain", 220, Rarity.UNCOMMON, mage.cards.p.PsychicDrain.class)); cards.add(new SetCardInfo("Putrefy", 221, Rarity.UNCOMMON, mage.cards.p.Putrefy.class)); + cards.add(new SetCardInfo("Quickchange", 62, Rarity.COMMON, mage.cards.q.Quickchange.class)); cards.add(new SetCardInfo("Rain of Embers", 138, Rarity.COMMON, mage.cards.r.RainOfEmbers.class)); cards.add(new SetCardInfo("Rally the Righteous", 222, Rarity.COMMON, mage.cards.r.RallyTheRighteous.class)); cards.add(new SetCardInfo("Razia's Purification", 224, Rarity.RARE, mage.cards.r.RaziasPurification.class)); cards.add(new SetCardInfo("Razia, Boros Archangel", 223, Rarity.RARE, mage.cards.r.RaziaBorosArchangel.class)); cards.add(new SetCardInfo("Recollect", 178, Rarity.UNCOMMON, mage.cards.r.Recollect.class)); cards.add(new SetCardInfo("Remand", 63, Rarity.UNCOMMON, mage.cards.r.Remand.class)); + cards.add(new SetCardInfo("Reroute", 139, Rarity.UNCOMMON, mage.cards.r.Reroute.class)); cards.add(new SetCardInfo("Ribbons of Night", 101, Rarity.UNCOMMON, mage.cards.r.RibbonsOfNight.class)); cards.add(new SetCardInfo("Rolling Spoil", 179, Rarity.UNCOMMON, mage.cards.r.RollingSpoil.class)); cards.add(new SetCardInfo("Roofstalker Wight", 102, Rarity.COMMON, mage.cards.r.RoofstalkerWight.class)); @@ -344,5 +346,6 @@ public class RavnicaCityOfGuilds extends ExpansionSet { cards.add(new SetCardInfo("Wojek Embermage", 152, Rarity.UNCOMMON, mage.cards.w.WojekEmbermage.class)); cards.add(new SetCardInfo("Wojek Siren", 37, Rarity.COMMON, mage.cards.w.WojekSiren.class)); cards.add(new SetCardInfo("Woodwraith Strangler", 241, Rarity.COMMON, mage.cards.w.WoodwraithStrangler.class)); + cards.add(new SetCardInfo("Zephyr Spirit", 76, Rarity.COMMON, mage.cards.z.ZephyrSpirit.class)); } } diff --git a/Mage/src/main/java/mage/filter/FilterAbility.java b/Mage/src/main/java/mage/filter/FilterAbility.java index b3f5ebfe280..80af830d142 100644 --- a/Mage/src/main/java/mage/filter/FilterAbility.java +++ b/Mage/src/main/java/mage/filter/FilterAbility.java @@ -43,6 +43,10 @@ public class FilterAbility extends FilterImpl { super(""); } + public FilterAbility(String name) { + super(name); + } + public FilterAbility(FilterAbility filter) { super(filter); } diff --git a/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java b/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java index a8a63557026..10f2a786f97 100644 --- a/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java +++ b/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; import mage.constants.AbilityType; import mage.constants.Zone; import mage.filter.Filter; @@ -46,15 +47,23 @@ import mage.target.TargetObject; */ public class TargetActivatedAbility extends TargetObject { + protected final FilterAbility filter; + public TargetActivatedAbility() { + this(new FilterAbility()); + } + + public TargetActivatedAbility(FilterAbility filter) { this.minNumberOfTargets = 1; this.maxNumberOfTargets = 1; this.zone = Zone.STACK; this.targetName = "activated ability"; + this.filter = filter; } public TargetActivatedAbility(final TargetActivatedAbility target) { super(target); + this.filter = target.filter.copy(); } @Override @@ -63,7 +72,8 @@ public class TargetActivatedAbility extends TargetObject { return false; } StackObject stackObject = game.getStack().getStackObject(id); - return stackObject != null && stackObject.getStackAbility() != null && stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED; + return stackObject != null && stackObject.getStackAbility() != null && stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED + && filter.match(((ActivatedAbility) stackObject), game); } @Override @@ -73,13 +83,13 @@ public class TargetActivatedAbility extends TargetObject { @Override public boolean canChoose(UUID sourceControllerId, Game game) { - for (StackObject stackObject : game.getStack()) { - if (stackObject.getStackAbility() != null + for (StackObject stackObject : game.getStack()) { + if (stackObject.getStackAbility() != null && stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED && game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getStackAbility().getControllerId())) { - return true; - } + return true; } + } return false; } @@ -92,7 +102,9 @@ public class TargetActivatedAbility extends TargetObject { public Set possibleTargets(UUID sourceControllerId, Game game) { Set possibleTargets = new HashSet<>(); for (StackObject stackObject : game.getStack()) { - if (stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED && game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getStackAbility().getControllerId())) { + if (stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED + && game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getStackAbility().getControllerId()) + && filter.match(((ActivatedAbility) stackObject), game)) { possibleTargets.add(stackObject.getStackAbility().getId()); } } @@ -108,7 +120,7 @@ public class TargetActivatedAbility extends TargetObject { public Filter getFilter() { return new FilterAbility(); } - + @Override public String getTargetedName(Game game) { StringBuilder sb = new StringBuilder("activated ability (");