From 3f62c8d8969ba8685baf32db74cb7aef96ead6c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 21 Oct 2017 13:07:54 -0400 Subject: [PATCH 1/8] Implemented Prismatic Ward --- Mage.Sets/src/mage/cards/p/PrismaticWard.java | 129 ++++++++++++++++++ Mage.Sets/src/mage/sets/FifthEdition.java | 1 + Mage.Sets/src/mage/sets/IceAge.java | 1 + 3 files changed, 131 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PrismaticWard.java diff --git a/Mage.Sets/src/mage/cards/p/PrismaticWard.java b/Mage.Sets/src/mage/cards/p/PrismaticWard.java new file mode 100644 index 0000000000..3d5c31ec3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrismaticWard.java @@ -0,0 +1,129 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageObject; +import mage.ObjectColor; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class PrismaticWard extends CardImpl { + + public PrismaticWard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // As Prismatic Ward enters the battlefield, choose a color. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Benefit))); + + // Prevent all damage that would be dealt to enchanted creature by sources of the chosen color. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrismaticWardPreventDamageEffect())); + } + + public PrismaticWard(final PrismaticWard card) { + super(card); + } + + @Override + public PrismaticWard copy() { + return new PrismaticWard(this); + } +} + +class PrismaticWardPreventDamageEffect extends PreventionEffectImpl { + + public PrismaticWardPreventDamageEffect() { + super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false); + staticText = "Prevent all damage that would be dealt to enchanted creature by sources of the chosen color."; + } + + public PrismaticWardPreventDamageEffect(final PrismaticWardPreventDamageEffect effect) { + super(effect); + } + + @Override + public PrismaticWardPreventDamageEffect copy() { + return new PrismaticWardPreventDamageEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!super.applies(event, source, game)) { + return false; + } + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color"); + if (color == null) { + return false; + } + MageObject sourceObject = game.getObject(event.getSourceId()); + if (sourceObject == null || !sourceObject.getColor(game).shares(color)) { + return false; + } + Permanent attachment = game.getPermanent(source.getSourceId()); + if (attachment != null + && attachment.getAttachedTo() != null + && event.getTargetId().equals(attachment.getAttachedTo())) { + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index 58f3d4975c..95969ca6bb 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -328,6 +328,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Pradesh Gypsies", 179, Rarity.COMMON, mage.cards.p.PradeshGypsies.class)); cards.add(new SetCardInfo("Primal Clay", 395, Rarity.RARE, mage.cards.p.PrimalClay.class)); cards.add(new SetCardInfo("Primal Order", 180, Rarity.RARE, mage.cards.p.PrimalOrder.class)); + cards.add(new SetCardInfo("Prismatic Ward", 329, Rarity.COMMON, mage.cards.p.PrismaticWard.class)); cards.add(new SetCardInfo("Prodigal Sorcerer", 112, Rarity.COMMON, mage.cards.p.ProdigalSorcerer.class)); cards.add(new SetCardInfo("Psychic Venom", 113, Rarity.COMMON, mage.cards.p.PsychicVenom.class)); cards.add(new SetCardInfo("Pyroblast", 262, Rarity.UNCOMMON, mage.cards.p.Pyroblast.class)); diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 8db2063fca..e42c624e1f 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -253,6 +253,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Portent", 90, Rarity.COMMON, mage.cards.p.Portent.class)); cards.add(new SetCardInfo("Power Sink", 91, Rarity.COMMON, mage.cards.p.PowerSink.class)); cards.add(new SetCardInfo("Pox", 46, Rarity.RARE, mage.cards.p.Pox.class)); + cards.add(new SetCardInfo("Prismatic Ward", 271, Rarity.COMMON, mage.cards.p.PrismaticWard.class)); cards.add(new SetCardInfo("Pygmy Allosaurus", 145, Rarity.RARE, mage.cards.p.PygmyAllosaurus.class)); cards.add(new SetCardInfo("Pyknite", 146, Rarity.COMMON, mage.cards.p.Pyknite.class)); cards.add(new SetCardInfo("Pyroblast", 213, Rarity.COMMON, mage.cards.p.Pyroblast.class)); From f29141605b9325340470a565a69d94dbb805ed5f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 22 Oct 2017 09:16:51 -0400 Subject: [PATCH 2/8] fixed Nissa, Genesis Mage -10 forcing players to put 10 cards into play in order to continue --- .../src/mage/cards/n/NissaGenesisMage.java | 20 ++++++++++++------- .../LookLibraryAndPickControllerEffect.java | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NissaGenesisMage.java b/Mage.Sets/src/mage/cards/n/NissaGenesisMage.java index f06bd347c3..9322cd16cb 100644 --- a/Mage.Sets/src/mage/cards/n/NissaGenesisMage.java +++ b/Mage.Sets/src/mage/cards/n/NissaGenesisMage.java @@ -42,8 +42,7 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.common.FilterLandPermanent; +import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.target.common.TargetCreaturePermanent; @@ -55,6 +54,15 @@ import mage.target.common.TargetLandPermanent; */ public class NissaGenesisMage extends CardImpl { + private static final FilterCard filter = new FilterCard("any number of creature and/or land cards"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND) + )); + } + public NissaGenesisMage(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{5}{G}{G}"); this.addSuperType(SuperType.LEGENDARY); @@ -64,8 +72,8 @@ public class NissaGenesisMage extends CardImpl { //+2: Untap up to two target creatures and up to two target lands. Ability ability = new LoyaltyAbility(new UntapTargetEffect(false).setText("Untap up to two target creatures and up to two target lands"), +2); - ability.addTarget(new TargetCreaturePermanent(0, 2, new FilterCreaturePermanent("target creatures"), false)); - ability.addTarget(new TargetLandPermanent(0, 2, new FilterLandPermanent("target land"), false)); + ability.addTarget(new TargetCreaturePermanent(0, 2, StaticFilters.FILTER_PERMANENT_CREATURES, false)); + ability.addTarget(new TargetLandPermanent(0, 2, StaticFilters.FILTER_LANDS, false)); this.addAbility(ability); //-3: Target creature gets +5/+5 until end of turn. @@ -74,10 +82,8 @@ public class NissaGenesisMage extends CardImpl { this.addAbility(ability); //-10: Look at the top ten cards of your library. You may put any number of creature and/or land cards from among them onto the battlefield. Put the rest on the bottom of your library in a random order.); - FilterCard filter = new FilterCard("creature and/or land cards"); - filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND))); this.addAbility(new LoyaltyAbility( - new LookLibraryAndPickControllerEffect(10, 10, filter, false, false, Zone.BATTLEFIELD, true).setBackInRandomOrder(true), + new LookLibraryAndPickControllerEffect(10, 10, filter, false, true, Zone.BATTLEFIELD, false).setBackInRandomOrder(true), -10)); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index 5a93cbae46..99958198d3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -270,7 +270,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff } else { sb.append('P'); } - sb.append("put ").append(filter.getMessage()).append(" from among them onto the "); + sb.append("ut ").append(filter.getMessage()).append(" from among them onto the "); } else { sb.append(". Put "); if (numberToPick.calculate(null, null, this) > 1) { From 2809db6bb2da64e6ed3fef6ea1533ec729a1dffe Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 23 Oct 2017 22:02:59 -0400 Subject: [PATCH 3/8] Implemented Shade's Breath --- .../src/mage/cards/s/SquealingDevil.java | 32 ++++++++----------- Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SquealingDevil.java b/Mage.Sets/src/mage/cards/s/SquealingDevil.java index eb94a17919..6ee5d21756 100644 --- a/Mage.Sets/src/mage/cards/s/SquealingDevil.java +++ b/Mage.Sets/src/mage/cards/s/SquealingDevil.java @@ -33,7 +33,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.ManaWasSpentCondition; -import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; @@ -48,10 +47,8 @@ import mage.constants.ColoredManaSymbol; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import mage.watchers.common.ManaSpentToCastWatcher; /** @@ -105,23 +102,20 @@ class SquealingDevilEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); ManaCosts cost = new ManaCostsImpl("{X}"); - if (player != null) { - if (player.chooseUse(Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game)) { - int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); - cost.add(new GenericManaCost(costX)); - if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null && permanent.isCreature()) { - ContinuousEffect effect = new BoostTargetEffect(costX, 0, Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(permanent.getId())); - game.addEffect(effect, source); - return true; - } - return false; - } - } + if (player == null) { + return false; } - return false; + if (!player.chooseUse(Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game)) { + return false; + } + int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); + cost.setX(costX); + if (!cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { + return false; + } + ContinuousEffect effect = new BoostTargetEffect(costX, 0, Duration.EndOfTurn); + game.addEffect(effect, source); + return true; } @Override diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index f8311aadc5..9171d2dcfe 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -260,6 +260,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Secluded Steppe", 324, Rarity.COMMON, mage.cards.s.SecludedSteppe.class)); cards.add(new SetCardInfo("Serpentine Basilisk", 280, Rarity.UNCOMMON, mage.cards.s.SerpentineBasilisk.class)); cards.add(new SetCardInfo("Severed Legion", 166, Rarity.COMMON, mage.cards.s.SeveredLegion.class)); + cards.add(new SetCardInfo("Shade's Breath", 167, Rarity.UNCOMMON, mage.cards.s.ShadesBreath.class)); cards.add(new SetCardInfo("Shaleskin Bruiser", 226, Rarity.UNCOMMON, mage.cards.s.ShaleskinBruiser.class)); cards.add(new SetCardInfo("Shared Triumph", 53, Rarity.RARE, mage.cards.s.SharedTriumph.class)); cards.add(new SetCardInfo("Shepherd of Rot", 168, Rarity.COMMON, mage.cards.s.ShepherdOfRot.class)); From a6e066b2672e98931b69138db97756dc2fd30d4c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 23 Oct 2017 22:15:08 -0400 Subject: [PATCH 4/8] Implemented Goblin Machinist --- .../src/mage/cards/g/GoblinMachinist.java | 122 ++++++++++++++++++ Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 123 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinMachinist.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinMachinist.java b/Mage.Sets/src/mage/cards/g/GoblinMachinist.java new file mode 100644 index 0000000000..4253d92c1b --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinMachinist.java @@ -0,0 +1,122 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Library; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class GoblinMachinist extends CardImpl { + + public GoblinMachinist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(0); + this.toughness = new MageInt(5); + + // {2}{R}: Reveal cards from the top of your library until you reveal a nonland card. Goblin Machinist gets +X/+0 until end of turn, where X is that card's converted mana cost. Put the revealed cards on the bottom of your library in any order. + this.addAbility(new SimpleActivatedAbility(new GoblinMachinistEffect(), new ManaCostsImpl("{2}{R}"))); + } + + public GoblinMachinist(final GoblinMachinist card) { + super(card); + } + + @Override + public GoblinMachinist copy() { + return new GoblinMachinist(this); + } +} + +class GoblinMachinistEffect extends OneShotEffect { + + public GoblinMachinistEffect() { + super(Outcome.DrawCard); + this.staticText = "Reveal cards from the top of your library until you reveal a nonland card. {this} gets +X/+0 until end of turn, where X is that card's converted mana cost. Put the revealed cards on the bottom of your library in any order"; + } + + public GoblinMachinistEffect(final GoblinMachinistEffect effect) { + super(effect); + } + + @Override + public GoblinMachinistEffect copy() { + return new GoblinMachinistEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + if (controller.getLibrary().hasCards()) { + + CardsImpl cards = new CardsImpl(); + Library library = controller.getLibrary(); + Card card = null; + do { + card = library.removeFromTop(game); + if (card != null) { + cards.add(card); + } + } while (library.hasCards() && card != null && card.isLand()); + if (!cards.isEmpty()) { + controller.revealCards(sourceObject.getIdName(), cards, game); + } + boolean retVal = false; + if (card != null) { + retVal = new BoostSourceEffect(card.getConvertedManaCost(), 0, Duration.EndOfTurn).apply(game, source); + } + return controller.putCardsOnBottomOfLibrary(cards, game, source, true) && retVal; + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index 9171d2dcfe..335a165dbd 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -145,6 +145,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Glory Seeker", 31, Rarity.COMMON, mage.cards.g.GlorySeeker.class)); cards.add(new SetCardInfo("Gluttonous Zombie", 151, Rarity.UNCOMMON, mage.cards.g.GluttonousZombie.class)); cards.add(new SetCardInfo("Goblin Burrows", 318, Rarity.UNCOMMON, mage.cards.g.GoblinBurrows.class)); + cards.add(new SetCardInfo("Goblin Machinist", 204, Rarity.UNCOMMON, mage.cards.g.GoblinMachinist.class)); cards.add(new SetCardInfo("Goblin Piledriver", 205, Rarity.RARE, mage.cards.g.GoblinPiledriver.class)); cards.add(new SetCardInfo("Goblin Pyromancer", 206, Rarity.RARE, mage.cards.g.GoblinPyromancer.class)); cards.add(new SetCardInfo("Goblin Sharpshooter", 207, Rarity.RARE, mage.cards.g.GoblinSharpshooter.class)); From 2e3c916717646815626dc94f633f48273efe0f74 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 24 Oct 2017 07:39:19 -0400 Subject: [PATCH 5/8] fixed an incorrect commit --- Mage.Sets/src/mage/cards/s/ShadesBreath.java | 143 ++++++++++++++++++ .../src/mage/cards/s/SquealingDevil.java | 32 ++-- 2 files changed, 162 insertions(+), 13 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/ShadesBreath.java diff --git a/Mage.Sets/src/mage/cards/s/ShadesBreath.java b/Mage.Sets/src/mage/cards/s/ShadesBreath.java new file mode 100644 index 0000000000..c3580f87f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShadesBreath.java @@ -0,0 +1,143 @@ +/* + * 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.List; +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.SubTypeList; + +/** + * + * @author TheElk801 + */ +public class ShadesBreath extends CardImpl { + + public ShadesBreath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // Until end of turn, each creature you control becomes a black Shade and gains "{B}: This creature gets +1/+1 until end of turn." + this.getSpellAbility().addEffect(new ShadesBreathSetColorEffect()); + this.getSpellAbility().addEffect(new ShadesBreathSetSubtypeEffect()); + this.getSpellAbility().addEffect( + new GainAbilityControlledEffect(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostSourceEffect(1, 1, Duration.EndOfTurn).setText("this creature gets +1/+1 until end of turn"), + new ManaCostsImpl("{B}") + ), Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_A_CREATURE) + .setText("and gains \"{B}: This creature gets +1/+1 until end of turn.\"") + ); + } + + public ShadesBreath(final ShadesBreath card) { + super(card); + } + + @Override + public ShadesBreath copy() { + return new ShadesBreath(this); + } +} + +class ShadesBreathSetColorEffect extends ContinuousEffectImpl { + + public ShadesBreathSetColorEffect() { + super(Duration.EndOfTurn, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Benefit); + staticText = "Until end of turn, each creature you control becomes a black"; + } + + public ShadesBreathSetColorEffect(final ShadesBreathSetColorEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game); + for (Permanent permanent : permanents) { + if (permanent != null) { + permanent.getColor(game).setColor(ObjectColor.BLACK); + } + } + return true; + } + + @Override + public ShadesBreathSetColorEffect copy() { + return new ShadesBreathSetColorEffect(this); + } +} + +class ShadesBreathSetSubtypeEffect extends ContinuousEffectImpl { + + public ShadesBreathSetSubtypeEffect() { + super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + staticText = "Shade"; + } + + public ShadesBreathSetSubtypeEffect(final ShadesBreathSetSubtypeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game); + for (Permanent permanent : permanents) { + if (permanent != null) { + SubTypeList subtype = permanent.getSubtype(game); + if (subtype != null && subtype.size() != 1 || !subtype.contains(SubType.SHADE)) { + subtype.removeAll(SubType.getCreatureTypes(false)); + subtype.add(SubType.SHADE); + } + } + } + return true; + } + + @Override + public ShadesBreathSetSubtypeEffect copy() { + return new ShadesBreathSetSubtypeEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SquealingDevil.java b/Mage.Sets/src/mage/cards/s/SquealingDevil.java index 6ee5d21756..eb94a17919 100644 --- a/Mage.Sets/src/mage/cards/s/SquealingDevil.java +++ b/Mage.Sets/src/mage/cards/s/SquealingDevil.java @@ -33,6 +33,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.ManaWasSpentCondition; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; @@ -47,8 +48,10 @@ import mage.constants.ColoredManaSymbol; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; import mage.watchers.common.ManaSpentToCastWatcher; /** @@ -102,20 +105,23 @@ class SquealingDevilEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); ManaCosts cost = new ManaCostsImpl("{X}"); - if (player == null) { - return false; + if (player != null) { + if (player.chooseUse(Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game)) { + int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); + cost.add(new GenericManaCost(costX)); + if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null && permanent.isCreature()) { + ContinuousEffect effect = new BoostTargetEffect(costX, 0, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + return true; + } + return false; + } + } } - if (!player.chooseUse(Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game)) { - return false; - } - int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); - cost.setX(costX); - if (!cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { - return false; - } - ContinuousEffect effect = new BoostTargetEffect(costX, 0, Duration.EndOfTurn); - game.addEffect(effect, source); - return true; + return false; } @Override From 3746fddf54c8ed2b20cf265c2fd147449ec0c825 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 25 Oct 2017 07:24:49 -0400 Subject: [PATCH 6/8] fixed Angelic Accord displaying the wrong amount of life gain required (fixes #4132 and #4133) --- .../abilities/condition/common/YouGainedLifeCondition.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/condition/common/YouGainedLifeCondition.java b/Mage/src/main/java/mage/abilities/condition/common/YouGainedLifeCondition.java index f19ff14b8e..a33a4d9bd0 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/YouGainedLifeCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/YouGainedLifeCondition.java @@ -27,7 +27,6 @@ public class YouGainedLifeCondition extends IntCompareCondition { @Override public String toString() { - return String.format("if you gained %s or more life this turn ", value); + return String.format("if you gained %s or more life this turn ", value + 1); } } - From 15764549d45135ef53c80fe9494c1b64a75b880f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 25 Oct 2017 09:23:31 -0400 Subject: [PATCH 7/8] fixed Manaweft Sliver giving abilities to other player's creatures --- Mage.Sets/src/mage/cards/m/ManaweftSliver.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/ManaweftSliver.java b/Mage.Sets/src/mage/cards/m/ManaweftSliver.java index f26076952d..ff16a2ed6a 100644 --- a/Mage.Sets/src/mage/cards/m/ManaweftSliver.java +++ b/Mage.Sets/src/mage/cards/m/ManaweftSliver.java @@ -29,9 +29,8 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -39,7 +38,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; -import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; /** * @@ -47,6 +46,8 @@ import mage.filter.StaticFilters; */ public class ManaweftSliver extends CardImpl { + public static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.SLIVER, "Sliver creatures"); + public ManaweftSliver(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.SLIVER); @@ -55,11 +56,11 @@ public class ManaweftSliver extends CardImpl { this.toughness = new MageInt(1); // Sliver creatures you control have "{T}: Add one mana of any color to your mana pool." - Ability ability = new AnyColorManaAbility(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new GainAbilityAllEffect(ability, - Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, - "Sliver creatures you control have \"{T}: Add one mana of any color to your mana pool.\""))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect( + new AnyColorManaAbility(), + Duration.WhileOnBattlefield, + filter + ))); } public ManaweftSliver(final ManaweftSliver card) { From a8969b9676bc1a2c52d14f95206853984fc9e9ae Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 25 Oct 2017 09:47:49 -0400 Subject: [PATCH 8/8] small fix --- .../src/mage/cards/c/ChaliceOfTheVoid.java | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ChaliceOfTheVoid.java b/Mage.Sets/src/mage/cards/c/ChaliceOfTheVoid.java index d6b829d2be..cc53c2feb4 100644 --- a/Mage.Sets/src/mage/cards/c/ChaliceOfTheVoid.java +++ b/Mage.Sets/src/mage/cards/c/ChaliceOfTheVoid.java @@ -28,16 +28,14 @@ package mage.cards.c; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -53,7 +51,7 @@ import mage.target.targetpointer.FixedTarget; public class ChaliceOfTheVoid extends CardImpl { public ChaliceOfTheVoid(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{X}{X}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{X}{X}"); // Chalice of the Void enters the battlefield with X charge counters on it. this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.CHARGE.createInstance()))); @@ -75,7 +73,7 @@ public class ChaliceOfTheVoid extends CardImpl { class ChaliceOfTheVoidTriggeredAbility extends TriggeredAbilityImpl { public ChaliceOfTheVoidTriggeredAbility() { - super(Zone.BATTLEFIELD, new CounterEffect()); + super(Zone.BATTLEFIELD, new CounterTargetEffect()); } public ChaliceOfTheVoidTriggeredAbility(final ChaliceOfTheVoidTriggeredAbility abiltity) { @@ -110,25 +108,3 @@ class ChaliceOfTheVoidTriggeredAbility extends TriggeredAbilityImpl { return "Whenever a player casts a spell with converted mana cost equal to the number of charge counters on {this}, counter that spell."; } } - -class CounterEffect extends OneShotEffect { - - public CounterEffect() { - super(Outcome.Detriment); - } - - public CounterEffect(final CounterEffect effect) { - super(effect); - } - - @Override - public CounterEffect copy() { - return new CounterEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return game.getStack().counter(this.getTargetPointer().getFirst(game, source), source.getSourceId(), game); - } - -}