From 400f7744eebd268f45e8c846236b6070b5707a6f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 21:12:03 -0400 Subject: [PATCH 01/68] Implemented Brace for Impact --- .../src/mage/cards/b/BraceForImpact.java | 129 ++++++++++++++++++ Mage.Sets/src/mage/sets/Dissension.java | 1 + 2 files changed, 130 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BraceForImpact.java diff --git a/Mage.Sets/src/mage/cards/b/BraceForImpact.java b/Mage.Sets/src/mage/cards/b/BraceForImpact.java new file mode 100644 index 0000000000..dd6686b3c7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BraceForImpact.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.b; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.MulticoloredPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class BraceForImpact extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("multicolored creature"); + + static { + filter.add(new MulticoloredPredicate()); + } + + public BraceForImpact(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}"); + + // Prevent all damage that would be dealt to target multicolored creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature. + this.getSpellAbility().addEffect(new BraceForImpactPreventDamageTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public BraceForImpact(final BraceForImpact card) { + super(card); + } + + @Override + public BraceForImpact copy() { + return new BraceForImpact(this); + } +} + +class BraceForImpactPreventDamageTargetEffect extends PreventionEffectImpl { + + public BraceForImpactPreventDamageTargetEffect(Duration duration) { + super(duration); + staticText = "Prevent all damage that would be dealt to target multicolored creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature"; + } + + public BraceForImpactPreventDamageTargetEffect(final BraceForImpactPreventDamageTargetEffect effect) { + super(effect); + } + + @Override + public BraceForImpactPreventDamageTargetEffect copy() { + return new BraceForImpactPreventDamageTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false); + if (!game.replaceEvent(preventEvent)) { + int prevented = 0; + int damage = event.getAmount(); + event.setAmount(0); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), damage)); + prevented = damage; + + // add counters now + if (prevented > 0) { + Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget()); + if (targetPermanent != null) { + targetPermanent.addCounters(CounterType.P1P1.createInstance(prevented), source, game); + game.informPlayers(new StringBuilder("Brace for Impact: Prevented ").append(prevented).append(" damage ").toString()); + game.informPlayers("Brace for Impact: Adding " + prevented + " +1/+1 counters to " + targetPermanent.getName()); + } + } + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!this.used && super.applies(event, source, game)) { + if (source.getTargets().getFirstTarget().equals(event.getTargetId())) { + return true; + } + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index e476eea562..4be5af072a 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -71,6 +71,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Blood Crypt", 171, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Bond of Agony", 38, Rarity.UNCOMMON, mage.cards.b.BondOfAgony.class)); cards.add(new SetCardInfo("Bound // Determined", 149, Rarity.RARE, mage.cards.b.BoundDetermined.class)); + cards.add(new SetCardInfo("Brace for Impact", 5, Rarity.UNCOMMON, mage.cards.b.BraceForImpact.class)); cards.add(new SetCardInfo("Brain Pry", 39, Rarity.UNCOMMON, mage.cards.b.BrainPry.class)); cards.add(new SetCardInfo("Breeding Pool", 172, Rarity.RARE, mage.cards.b.BreedingPool.class)); cards.add(new SetCardInfo("Bronze Bombshell", 160, Rarity.RARE, mage.cards.b.BronzeBombshell.class)); From a9095d024c39e3053c6567e74595d4e3fbbe8ae8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 22:01:24 -0400 Subject: [PATCH 02/68] Implemented Unliving Psychopath --- .../src/mage/cards/u/UnlivingPsychopath.java | 104 ++++++++++++++++++ Mage.Sets/src/mage/sets/Dissension.java | 1 + 2 files changed, 105 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java diff --git a/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java b/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java new file mode 100644 index 0000000000..6018e49bca --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java @@ -0,0 +1,104 @@ +/* + * 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.u; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class UnlivingPsychopath extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power less than Unliving Psychopath's power"); + + static { + filter.add(new UnlivingPsychopathPowerLessThanSourcePredicate()); + } + + public UnlivingPsychopath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // {B}: Unliving Psychopath gets +1/-1 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, -1, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B))); + + // {B}, {tap}: Destroy target creature with power less than Unliving Psychopath's power. + Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ColoredManaCost(ColoredManaSymbol.B)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public UnlivingPsychopath(final UnlivingPsychopath card) { + super(card); + } + + @Override + public UnlivingPsychopath copy() { + return new UnlivingPsychopath(this); + } +} + +class UnlivingPsychopathPowerLessThanSourcePredicate implements ObjectSourcePlayerPredicate> { + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Permanent sourcePermanent = game.getPermanent(input.getSourceId()); + return sourcePermanent != null && input.getObject().getPower().getValue() < sourcePermanent.getPower().getValue(); + } + + @Override + public String toString() { + return "power less than Unliving Psychopath's power"; + } +} diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index 4be5af072a..3bc0aaaf64 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -199,6 +199,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Trial // Error", 158, Rarity.UNCOMMON, mage.cards.t.TrialError.class)); cards.add(new SetCardInfo("Trygon Predator", 133, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class)); cards.add(new SetCardInfo("Twinstrike", 134, Rarity.UNCOMMON, mage.cards.t.Twinstrike.class)); + cards.add(new SetCardInfo("Unliving Psychopath", 56, Rarity.RARE, mage.cards.u.UnlivingPsychopath.class)); cards.add(new SetCardInfo("Utopia Sprawl", 99, Rarity.COMMON, mage.cards.u.UtopiaSprawl.class)); cards.add(new SetCardInfo("Utvara Scalper", 76, Rarity.COMMON, mage.cards.u.UtvaraScalper.class)); cards.add(new SetCardInfo("Valor Made Real", 20, Rarity.COMMON, mage.cards.v.ValorMadeReal.class)); From 1c7cb16a269ca69ddea40e675a6d5b3e9de8bad7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 22:30:30 -0400 Subject: [PATCH 03/68] Implemented Ronom Serpent --- Mage.Sets/src/mage/cards/r/RonomSerpent.java | 85 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RonomSerpent.java diff --git a/Mage.Sets/src/mage/cards/r/RonomSerpent.java b/Mage.Sets/src/mage/cards/r/RonomSerpent.java new file mode 100644 index 0000000000..37fa43860b --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RonomSerpent.java @@ -0,0 +1,85 @@ +/* + * 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.MageInt; +import mage.abilities.common.ControlsPermanentsControllerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author TheElk801 + */ +public class RonomSerpent extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("a snow land"); + private static final FilterLandPermanent filter2 = new FilterLandPermanent("no snow lands"); + + static { + filter.add(new SupertypePredicate(SuperType.SNOW)); + filter2.add(new SupertypePredicate(SuperType.SNOW)); + } + + public RonomSerpent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); + + this.addSuperType(SuperType.SNOW); + this.subtype.add(SubType.SERPENT); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Ronom Serpent can't attack unless defending player controls a snow land. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackUnlessDefenderControllsPermanent(filter))); + + // When you control no snow lands, sacrifice Ronom Serpent. + this.addAbility(new ControlsPermanentsControllerTriggeredAbility( + filter2, ComparisonType.EQUAL_TO, 0, new SacrificeSourceEffect() + )); + } + + public RonomSerpent(final RonomSerpent card) { + super(card); + } + + @Override + public RonomSerpent copy() { + return new RonomSerpent(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 6b5ebe19bf..8eff23b2ec 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -149,6 +149,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Rimewind Taskmage", 44, Rarity.COMMON, mage.cards.r.RimewindTaskmage.class)); cards.add(new SetCardInfo("Rite of Flame", 96, Rarity.COMMON, mage.cards.r.RiteOfFlame.class)); cards.add(new SetCardInfo("Ronom Hulk", 119, Rarity.COMMON, mage.cards.r.RonomHulk.class)); + cards.add(new SetCardInfo("Ronom Serpent", 45, Rarity.COMMON, mage.cards.r.RonomSerpent.class)); cards.add(new SetCardInfo("Ronom Unicorn", 16, Rarity.COMMON, mage.cards.r.RonomUnicorn.class)); cards.add(new SetCardInfo("Rune Snag", 46, Rarity.COMMON, mage.cards.r.RuneSnag.class)); cards.add(new SetCardInfo("Scrying Sheets", 149, Rarity.RARE, mage.cards.s.ScryingSheets.class)); From 4450938662e00291f6fe06dfffb3ab30dbf50aa9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 23:04:42 -0400 Subject: [PATCH 04/68] Implemented Earthen Goo --- Mage.Sets/src/mage/cards/e/EarthenGoo.java | 88 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 2 files changed, 89 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EarthenGoo.java diff --git a/Mage.Sets/src/mage/cards/e/EarthenGoo.java b/Mage.Sets/src/mage/cards/e/EarthenGoo.java new file mode 100644 index 0000000000..4778ddaf7b --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EarthenGoo.java @@ -0,0 +1,88 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.OrCost; +import mage.constants.SubType; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class EarthenGoo extends CardImpl { + + public EarthenGoo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.OOZE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Cumulative upkeep {R} or {G} + this.addAbility(new CumulativeUpkeepAbility(new OrCost( + new ManaCostsImpl("{R}"), + new ManaCostsImpl("{G}"), + "{R} or {G}" + ))); + + // Earthen Goo gets +1/+1 for each age counter on it. + DynamicValue value = new CountersSourceCount(CounterType.AGE); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new BoostSourceEffect(value, value, Duration.WhileOnBattlefield) + .setText("{this} gets +1/+1 for each age counter on it") + )); + } + + public EarthenGoo(final EarthenGoo card) { + super(card); + } + + @Override + public EarthenGoo copy() { + return new EarthenGoo(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 8eff23b2ec..455db5ecd8 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -84,6 +84,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Diamond Faerie", 128, Rarity.RARE, mage.cards.d.DiamondFaerie.class)); cards.add(new SetCardInfo("Disciple of Tevesh Szat", 55, Rarity.COMMON, mage.cards.d.DiscipleOfTeveshSzat.class)); cards.add(new SetCardInfo("Drelnoch", 32, Rarity.COMMON, mage.cards.d.Drelnoch.class)); + cards.add(new SetCardInfo("Earthen Goo", 80, Rarity.UNCOMMON, mage.cards.e.EarthenGoo.class)); cards.add(new SetCardInfo("Field Marshal", 5, Rarity.RARE, mage.cards.f.FieldMarshal.class)); cards.add(new SetCardInfo("Flashfreeze", 33, Rarity.UNCOMMON, mage.cards.f.Flashfreeze.class)); cards.add(new SetCardInfo("Freyalise's Radiance", 108, Rarity.UNCOMMON, mage.cards.f.FreyalisesRadiance.class)); From e223a2678ac36e69dd5887a2eef6552f3711138d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 23:15:21 -0400 Subject: [PATCH 05/68] Implemented Magmatic Core --- Mage.Sets/src/mage/cards/m/MagmaticCore.java | 78 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MagmaticCore.java diff --git a/Mage.Sets/src/mage/cards/m/MagmaticCore.java b/Mage.Sets/src/mage/cards/m/MagmaticCore.java new file mode 100644 index 0000000000..7cd7f3afcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MagmaticCore.java @@ -0,0 +1,78 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author TheElk801 + */ +public class MagmaticCore extends CardImpl { + + public MagmaticCore(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // At the beginning of your end step, Magmatic Core deals X damage divided as you choose among any number of target creatures, where X is the number of age counters on it. + DynamicValue value = new CountersSourceCount(CounterType.AGE); + Ability ability = new BeginningOfEndStepTriggeredAbility( + new DamageMultiEffect(value) + .setText("{this} deals X damage divided as you choose " + + "among any number of target creatures," + + " where X is the number of age counters on it."), + TargetController.YOU, false + ); + ability.addTarget(new TargetCreaturePermanentAmount(value)); + this.addAbility(ability); + } + + public MagmaticCore(final MagmaticCore card) { + super(card); + } + + @Override + public MagmaticCore copy() { + return new MagmaticCore(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 455db5ecd8..0a4885027c 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -124,6 +124,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Lightning Storm", 89, Rarity.UNCOMMON, mage.cards.l.LightningStorm.class)); cards.add(new SetCardInfo("Lovisa Coldeyes", 90, Rarity.RARE, mage.cards.l.LovisaColdeyes.class)); cards.add(new SetCardInfo("Luminesce", 14, Rarity.UNCOMMON, mage.cards.l.Luminesce.class)); + cards.add(new SetCardInfo("Magmatic Core", 91, Rarity.UNCOMMON, mage.cards.m.MagmaticCore.class)); cards.add(new SetCardInfo("Martyr of Ashes", 92, Rarity.COMMON, mage.cards.m.MartyrOfAshes.class)); cards.add(new SetCardInfo("Martyr of Bones", 65, Rarity.COMMON, mage.cards.m.MartyrOfBones.class)); cards.add(new SetCardInfo("Martyr of Frost", 40, Rarity.COMMON, mage.cards.m.MartyrOfFrost.class)); From 116104db58874ff1f364f42c1cc92517125f5663 Mon Sep 17 00:00:00 2001 From: igoudt Date: Sun, 1 Oct 2017 09:59:15 +0200 Subject: [PATCH 06/68] replace loops in triggeredabilities to lambdas --- .../mage/abilities/TriggeredAbilities.java | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java index a8eebfb296..5feca7f7af 100644 --- a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java +++ b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java @@ -30,7 +30,6 @@ package mage.abilities; import mage.MageObject; import mage.constants.Zone; -import mage.designations.Designation; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.NumberOfTriggersEvent; @@ -41,12 +40,11 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** - * * @author BetaSteward_at_googlemail.com - * - * This class uses ConcurrentHashMap to avoid ConcurrentModificationExceptions. - * See ticket https://github.com/magefree/mage/issues/966 and - * https://github.com/magefree/mage/issues/473 + *

+ * This class uses ConcurrentHashMap to avoid ConcurrentModificationExceptions. + * See ticket https://github.com/magefree/mage/issues/966 and + * https://github.com/magefree/mage/issues/473 */ public class TriggeredAbilities extends ConcurrentHashMap { @@ -65,7 +63,7 @@ public class TriggeredAbilities extends ConcurrentHashMap it = this.values().iterator(); it.hasNext();) { + for (Iterator it = this.values().iterator(); it.hasNext(); ) { TriggeredAbility ability = it.next(); if (ability instanceof StateTriggeredAbility && ((StateTriggeredAbility) ability).canTrigger(game)) { checkTrigger(ability, null, game); @@ -74,7 +72,7 @@ public class TriggeredAbilities extends ConcurrentHashMap it = this.values().iterator(); it.hasNext();) { + for (Iterator it = this.values().iterator(); it.hasNext(); ) { TriggeredAbility ability = it.next(); if (ability.checkEventType(event, game)) { checkTrigger(ability, event, game); @@ -132,8 +130,8 @@ public class TriggeredAbilities extends ConcurrentHashMap keysToRemove = new ArrayList<>(); - for (String key : this.keySet()) { - if (key.endsWith(sourceId.toString())) { - keysToRemove.add(key); - } - } - for (String key : keysToRemove) { - remove(key); - } + keySet().removeIf(key -> key.endsWith(sourceId.toString())); } public void removeAllGainedAbilities() { @@ -182,19 +173,10 @@ public class TriggeredAbilities extends ConcurrentHashMap keysToRemove = new ArrayList<>(); - Abilities: - for (Entry entry : this.entrySet()) { - if (game.getObject(entry.getValue().getSourceId()) == null) { - for (Designation designation : game.getState().getDesignations()) { - if (designation.getId().equals(entry.getValue().getSourceId())) { - continue Abilities; - } - } - keysToRemove.add(entry.getKey()); - } - } - this.keySet().removeAll(keysToRemove); + + entrySet().removeIf(entry -> game.getObject(entry.getValue().getSourceId()) == null + && game.getState().getDesignations().stream().noneMatch(designation -> designation.getId().equals(entry.getValue().getSourceId()))); + } public TriggeredAbilities copy() { From e9b18b561867d5509625457a0fb7fb5f66a2130b Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 1 Oct 2017 19:07:13 +1030 Subject: [PATCH 07/68] 2421: Fixed Dubious Challenge to make cards enter the battlefield in correct order. --- .../src/mage/cards/d/DubiousChallenge.java | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java index ed2b4c02e2..3adb0f3683 100644 --- a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java +++ b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java @@ -53,6 +53,8 @@ public class DubiousChallenge extends CardImpl { // Look at the top ten cards of your library, exile up to two creature cards from among them, then shuffle your library. Target opponent may choose one of the exiled cards and put it onto the battlefield under his or her control. Put the rest onto the battlefield under your control. getSpellAbility().addEffect(new DubiousChallengeEffect()); getSpellAbility().addTarget(new TargetOpponent()); + getSpellAbility().addEffect(new DubiousChallengeMoveToBattlefieldEffect()); + getSpellAbility().addEffect(new DubiousChallengeMoveToBattlefieldEffect()); } public DubiousChallenge(final DubiousChallenge card) { @@ -69,7 +71,7 @@ class DubiousChallengeEffect extends OneShotEffect { public DubiousChallengeEffect() { super(Outcome.Benefit); - this.staticText = "Look at the top ten cards of your library, exile up to two creature cards from among them, then shuffle your library. Target opponent may choose one of the exiled cards and put it onto the battlefield under his or her control. Put the rest onto the battlefield under your control"; + this.staticText = "Look at the top ten cards of your library, exile up to two creature cards from among them, then shuffle your library. Target opponent may choose one of the exiled cards and put it onto the battlefield under his or her control. Put the rest onto the battlefield under your control."; } public DubiousChallengeEffect(final DubiousChallengeEffect effect) { @@ -98,15 +100,17 @@ class DubiousChallengeEffect extends OneShotEffect { Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); if (opponent != null) { TargetCard targetOpponentCreature = new TargetCard(0, 1, Zone.EXILED, new FilterCreatureCard()); + DubiousChallengeMoveToBattlefieldEffect opponentEffect = (DubiousChallengeMoveToBattlefieldEffect) source.getEffects().get(1); + DubiousChallengeMoveToBattlefieldEffect controllerEffect = (DubiousChallengeMoveToBattlefieldEffect) source.getEffects().get(2); if (opponent.choose(outcome, exiledCards, targetOpponentCreature, game)) { Card card = game.getCard(targetOpponentCreature.getFirstTarget()); if (card != null) { - opponent.moveCards(card, Zone.BATTLEFIELD, source, game); + opponentEffect.setPlayerAndCards(opponent, new CardsImpl(card)); exiledCards.remove(card); } } if (!exiledCards.isEmpty()) { - controller.moveCards(exiledCards, Zone.BATTLEFIELD, source, game); + controllerEffect.setPlayerAndCards(controller, exiledCards); } } } else { @@ -117,3 +121,36 @@ class DubiousChallengeEffect extends OneShotEffect { return false; } } + +class DubiousChallengeMoveToBattlefieldEffect extends OneShotEffect { + + public DubiousChallengeMoveToBattlefieldEffect() { + super(Outcome.Benefit); + } + + public DubiousChallengeMoveToBattlefieldEffect(final DubiousChallengeMoveToBattlefieldEffect effect) { + super(effect); + } + + @Override + public DubiousChallengeMoveToBattlefieldEffect copy() { + return new DubiousChallengeMoveToBattlefieldEffect(this); + } + + public void setPlayerAndCards(Player targetPlayer, Cards targetCards) + { + this.player = targetPlayer; + this.cards = targetCards; + } + + @Override + public boolean apply(Game game, Ability source) { + if (cards != null && player != null) { + return player.moveCards(cards, Zone.BATTLEFIELD, source, game); + } + return false; + } + + private Cards cards; + private Player player; +} \ No newline at end of file From 3e208af490303efab129299c77bb9d9d69b1542e Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 1 Oct 2017 19:10:16 +1030 Subject: [PATCH 08/68] 2421: added newline --- Mage.Sets/src/mage/cards/d/DubiousChallenge.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java index 3adb0f3683..cd973d7619 100644 --- a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java +++ b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java @@ -153,4 +153,4 @@ class DubiousChallengeMoveToBattlefieldEffect extends OneShotEffect { private Cards cards; private Player player; -} \ No newline at end of file +} From d3ff8e681490ceb90bee4644c357839eef1d40f1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 30 Sep 2017 23:26:19 -0400 Subject: [PATCH 09/68] updated Yasova Dragonclaw and Unliving Psychopath's predicates to prevent target invalidation when they die --- Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java | 2 +- Mage.Sets/src/mage/cards/y/YasovaDragonclaw.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java b/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java index 6018e49bca..223d5836e6 100644 --- a/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java +++ b/Mage.Sets/src/mage/cards/u/UnlivingPsychopath.java @@ -93,7 +93,7 @@ class UnlivingPsychopathPowerLessThanSourcePredicate implements ObjectSourcePlay @Override public boolean apply(ObjectSourcePlayer input, Game game) { - Permanent sourcePermanent = game.getPermanent(input.getSourceId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(input.getSourceId()); return sourcePermanent != null && input.getObject().getPower().getValue() < sourcePermanent.getPower().getValue(); } diff --git a/Mage.Sets/src/mage/cards/y/YasovaDragonclaw.java b/Mage.Sets/src/mage/cards/y/YasovaDragonclaw.java index 26aad6c555..3fcc58af8d 100644 --- a/Mage.Sets/src/mage/cards/y/YasovaDragonclaw.java +++ b/Mage.Sets/src/mage/cards/y/YasovaDragonclaw.java @@ -68,7 +68,7 @@ public class YasovaDragonclaw extends CardImpl { } public YasovaDragonclaw(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); @@ -83,7 +83,7 @@ public class YasovaDragonclaw extends CardImpl { effect2.setText(", untap that creature"); effect.addEffect(effect2); effect.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, ", and it gains haste until end of turn")); - Ability ability = new BeginningOfCombatTriggeredAbility(effect, TargetController.YOU, false); + Ability ability = new BeginningOfCombatTriggeredAbility(effect, TargetController.YOU, false); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } @@ -102,7 +102,7 @@ class YasovaDragonclawPowerLessThanSourcePredicate implements ObjectSourcePlayer @Override public boolean apply(ObjectSourcePlayer input, Game game) { - Permanent sourcePermanent = game.getPermanent(input.getSourceId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(input.getSourceId()); return sourcePermanent != null && input.getObject().getPower().getValue() < sourcePermanent.getPower().getValue(); } From ec3af500908276ea4a3a822dd2a88ad1c3858562 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 1 Oct 2017 11:24:52 -0400 Subject: [PATCH 10/68] Implemented Rohgahh of Kher Keep --- .../src/mage/cards/r/RohgahhOfKherKeep.java | 153 ++++++++++++++++++ Mage.Sets/src/mage/sets/Legends.java | 1 + .../src/mage/sets/MastersEditionIII.java | 1 + .../continuous/GainControlAllEffect.java | 17 +- 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/RohgahhOfKherKeep.java diff --git a/Mage.Sets/src/mage/cards/r/RohgahhOfKherKeep.java b/Mage.Sets/src/mage/cards/r/RohgahhOfKherKeep.java new file mode 100644 index 0000000000..9669a2fe5c --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RohgahhOfKherKeep.java @@ -0,0 +1,153 @@ +/* + * 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.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainControlAllEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class RohgahhOfKherKeep extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control named Kobolds of Kher Keep"); + + static { + filter.add(new NamePredicate("Kobolds of Kher Keep")); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public RohgahhOfKherKeep(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}{R}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.KOBOLD); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // At the beginning of your upkeep, you may pay {R}{R}{R}. If you don't, tap Rohgahh of Kher Keep and all creatures named Kobolds of Kher Keep, then an opponent gains control of them. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new RohgahhOfKherKeepEffect(), TargetController.YOU, false)); + + // Creatures you control named Kobolds of Kher Keep get +2/+2. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(2, 2, Duration.WhileOnBattlefield, filter, false))); + } + + public RohgahhOfKherKeep(final RohgahhOfKherKeep card) { + super(card); + } + + @Override + public RohgahhOfKherKeep copy() { + return new RohgahhOfKherKeep(this); + } +} + +class RohgahhOfKherKeepEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures named Kobolds of Kher Keep"); + + static { + filter.add(new NamePredicate("Kobolds of Kher Keep")); + } + + RohgahhOfKherKeepEffect() { + super(Outcome.Benefit); + this.staticText = "you may pay {R}{R}{R}. If you don't, tap {this} and all creatures named Kobolds of Kher Keep, then an opponent gains control of them."; + } + + RohgahhOfKherKeepEffect(final RohgahhOfKherKeepEffect effect) { + super(effect); + } + + @Override + public RohgahhOfKherKeepEffect copy() { + return new RohgahhOfKherKeepEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (player == null) { + return false; + } + Cost cost = new ManaCostsImpl("{R}{R}{R}"); + if (!cost.canPay(source, source.getSourceId(), player.getId(), game) + || !player.chooseUse(Outcome.Benefit, "Pay {R}{R}{R}?", source, game) + || !cost.pay(source, game, source.getSourceId(), player.getId(), false)) { + TargetOpponent target = new TargetOpponent(); + Player opponent = null; + if (target.choose(Outcome.Detriment, player.getId(), source.getSourceId(), game)) { + opponent = game.getPlayer(target.getFirstTarget()); + } + new TapAllEffect(filter).apply(game, source); + if (permanent != null) { + permanent.tap(game); + } + if (opponent != null) { + game.addEffect(new GainControlAllEffect(Duration.Custom, filter, opponent.getId()), source); + if (permanent != null) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, opponent.getId()); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 19a7d57de1..393cbee13f 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -213,6 +213,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Righteous Avengers", 203, Rarity.UNCOMMON, mage.cards.r.RighteousAvengers.class)); cards.add(new SetCardInfo("Ring of Immortals", 238, Rarity.RARE, mage.cards.r.RingOfImmortals.class)); cards.add(new SetCardInfo("Riven Turnbull", 294, Rarity.UNCOMMON, mage.cards.r.RivenTurnbull.class)); + cards.add(new SetCardInfo("Rohgahh of Kher Keep", 295, Rarity.RARE, mage.cards.r.RohgahhOfKherKeep.class)); cards.add(new SetCardInfo("Rubinia Soulsinger", 296, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); cards.add(new SetCardInfo("Rust", 49, Rarity.COMMON, mage.cards.r.Rust.class)); cards.add(new SetCardInfo("Sea Kings' Blessing", 75, Rarity.UNCOMMON, mage.cards.s.SeaKingsBlessing.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index 9ece206ed7..596bb603a2 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -200,6 +200,7 @@ public class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Reveka, Wizard Savant", 49, Rarity.UNCOMMON, mage.cards.r.RevekaWizardSavant.class)); cards.add(new SetCardInfo("Riding the Dilu Horse", 131, Rarity.UNCOMMON, mage.cards.r.RidingTheDiluHorse.class)); cards.add(new SetCardInfo("Riven Turnbull", 171, Rarity.UNCOMMON, mage.cards.r.RivenTurnbull.class)); + cards.add(new SetCardInfo("Rohgahh of Kher Keep", 172, Rarity.RARE, mage.cards.r.RohgahhOfKherKeep.class)); cards.add(new SetCardInfo("Rolling Earthquake", 110, Rarity.RARE, mage.cards.r.RollingEarthquake.class)); cards.add(new SetCardInfo("Rubinia Soulsinger", 173, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); cards.add(new SetCardInfo("Scrubland", 210, Rarity.RARE, mage.cards.s.Scrubland.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllEffect.java index 9cbe784ae8..ad85f73ad2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllEffect.java @@ -5,6 +5,7 @@ */ package mage.abilities.effects.common.continuous; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; @@ -22,16 +23,23 @@ import mage.game.permanent.Permanent; */ public class GainControlAllEffect extends ContinuousEffectImpl { - final FilterPermanent filter; + private final FilterPermanent filter; + private final UUID controllingPlayerId; public GainControlAllEffect(Duration duration, FilterPermanent filter) { + this(duration, filter, null); + } + + public GainControlAllEffect(Duration duration, FilterPermanent filter, UUID controllingPlayerId) { super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); this.filter = filter; + this.controllingPlayerId = controllingPlayerId; } public GainControlAllEffect(final GainControlAllEffect effect) { super(effect); this.filter = effect.filter.copy(); + this.controllingPlayerId = effect.controllingPlayerId; } @Override @@ -43,7 +51,12 @@ public class GainControlAllEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { if (permanent != null) { - permanent.changeControllerId(source.getControllerId(), game); + if (controllingPlayerId == null) { + permanent.changeControllerId(source.getControllerId(), game); + } else { + permanent.changeControllerId(controllingPlayerId, game); + } + } } return true; From aa6e4dfd6a50a01a3047128d8c52e5cc026c08c9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 1 Oct 2017 11:26:27 -0400 Subject: [PATCH 11/68] Fixed Admiral Beckett Brass bringing things it stole with it when stolen --- Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index ad910cbd04..5b92f7cd1f 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -78,7 +78,7 @@ public class AdmiralBeckettBrass extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. - Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom, true), TargetController.YOU, false); ability.addTarget(new TargetNonlandPermanent(filter2)); this.addAbility(ability, new DamagedByPiratesWatcher()); } From 6bde35f27561ff130cb08f8842cfa6cf877dddff Mon Sep 17 00:00:00 2001 From: igoudt Date: Mon, 2 Oct 2017 18:38:09 +0200 Subject: [PATCH 12/68] fixes #4079 --- .../org/mage/card/arcane/CardRendererUtils.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java index 89a6a5d173..6e3921f099 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java @@ -5,10 +5,7 @@ */ package org.mage.card.arcane; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Paint; +import java.awt.*; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Iterator; @@ -19,8 +16,8 @@ import java.util.regex.Pattern; /** * @author stravant@gmail.com - * - * Various static utilities for use in the card renderer + *

+ * Various static utilities for use in the card renderer */ public final class CardRendererUtils { @@ -124,6 +121,8 @@ public final class CardRendererUtils { } public static String killReminderText(String rule) { - return killReminderTextPattern.matcher(rule).replaceAll(""); + return killReminderTextPattern.matcher(rule).replaceAll("") + .replaceAll("", "") + .replaceAll("", ""); } } From 6b2c20b29ec79345756bd62f06123d2b3f2ef1ad Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 12:47:18 -0400 Subject: [PATCH 13/68] initial commit for changing CDAs interacting with Scarab God/God-Pharaoh's gift (untested)(#4082) --- Mage.Sets/src/mage/cards/g/GodPharaohsGift.java | 1 + Mage.Sets/src/mage/cards/h/HourOfEternity.java | 1 + .../src/mage/cards/q/QuicksilverGargantuan.java | 2 ++ Mage.Sets/src/mage/cards/t/Tarmogoyf.java | 2 +- Mage/src/main/java/mage/MageObject.java | 5 +++++ Mage/src/main/java/mage/MageObjectImpl.java | 15 +++++++++++++++ .../common/CreateTokenCopyTargetEffect.java | 2 ++ .../mage/abilities/keyword/EternalizeAbility.java | 1 + .../java/mage/game/permanent/token/Token.java | 4 ---- 9 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java b/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java index 279e6a8597..6f7c8d0ccc 100644 --- a/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java +++ b/Mage.Sets/src/mage/cards/g/GodPharaohsGift.java @@ -111,6 +111,7 @@ class GodPharaohsGiftEffect extends OneShotEffect { && cardChosen.moveToExile(exileId, sourceObject.getIdName(), source.getSourceId(), game)) { EmptyToken token = new EmptyToken(); CardUtil.copyTo(token).from(cardChosen); + token.removePTCDA(); token.getPower().modifyBaseValue(4); token.getToughness().modifyBaseValue(4); token.getColor(game).setColor(ObjectColor.BLACK); diff --git a/Mage.Sets/src/mage/cards/h/HourOfEternity.java b/Mage.Sets/src/mage/cards/h/HourOfEternity.java index 12c92247f2..813a8b3293 100644 --- a/Mage.Sets/src/mage/cards/h/HourOfEternity.java +++ b/Mage.Sets/src/mage/cards/h/HourOfEternity.java @@ -103,6 +103,7 @@ class HourOfEternityEffect extends OneShotEffect { if (game.getState().getZone(card.getId()) == Zone.EXILED) { EmptyToken token = new EmptyToken(); CardUtil.copyTo(token).from(card); + token.removePTCDA(); token.getPower().modifyBaseValue(4); token.getToughness().modifyBaseValue(4); token.getColor(game).setColor(ObjectColor.BLACK); diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverGargantuan.java b/Mage.Sets/src/mage/cards/q/QuicksilverGargantuan.java index 254507f8c9..df33757c0f 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverGargantuan.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverGargantuan.java @@ -72,6 +72,7 @@ class QuicksilverGargantuanApplyToPermanent extends ApplyToPermanent { @Override public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { + permanent.removePTCDA(); permanent.getPower().modifyBaseValue(7); permanent.getToughness().modifyBaseValue(7); return true; @@ -79,6 +80,7 @@ class QuicksilverGargantuanApplyToPermanent extends ApplyToPermanent { @Override public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) { + mageObject.removePTCDA(); mageObject.getPower().modifyBaseValue(7); mageObject.getToughness().modifyBaseValue(7); return true; diff --git a/Mage.Sets/src/mage/cards/t/Tarmogoyf.java b/Mage.Sets/src/mage/cards/t/Tarmogoyf.java index 9d6bbd78ec..3292df697a 100644 --- a/Mage.Sets/src/mage/cards/t/Tarmogoyf.java +++ b/Mage.Sets/src/mage/cards/t/Tarmogoyf.java @@ -73,7 +73,7 @@ public class Tarmogoyf extends CardImpl { class TarmogoyfEffect extends ContinuousEffectImpl { public TarmogoyfEffect() { - super(Duration.EndOfGame, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature); + super(Duration.EndOfGame, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, Outcome.BoostCreature); staticText = "{this}'s power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1"; } diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index 131dbe8efa..9982250353 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -17,8 +17,11 @@ import mage.util.SubTypeList; import java.io.Serializable; import java.util.EnumSet; +import java.util.Iterator; import java.util.List; import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; public interface MageObject extends MageItem, Serializable { @@ -198,6 +201,8 @@ public interface MageObject extends MageItem, Serializable { TextPart addTextPart(TextPart textPart); + public void removePTCDA(); + default void changeSubType(SubType fromSubType, SubType toSubType) { } diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java index 30c93e6fb0..44f5f42feb 100644 --- a/Mage/src/main/java/mage/MageObjectImpl.java +++ b/Mage/src/main/java/mage/MageObjectImpl.java @@ -29,6 +29,7 @@ package mage; import java.util.ArrayList; import java.util.EnumSet; +import java.util.Iterator; import java.util.List; import java.util.UUID; import mage.abilities.Abilities; @@ -38,12 +39,15 @@ import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; import mage.abilities.keyword.ChangelingAbility; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.text.TextPart; import mage.abilities.text.TextPartSubType; import mage.cards.FrameStyle; import mage.constants.CardType; +import mage.constants.SubLayer; import mage.constants.SubType; import mage.constants.SubTypeSet; import mage.constants.SuperType; @@ -338,4 +342,15 @@ public abstract class MageObjectImpl implements MageObject { } } + public void removePTCDA() { + for (Iterator iter = this.getAbilities().iterator(); iter.hasNext();) { + Ability ability = iter.next(); + for (Effect effect : ability.getEffects()) { + if (effect instanceof ContinuousEffect && ((ContinuousEffect) effect).getSublayer() == SubLayer.CharacteristicDefining_7a) { + iter.remove(); + break; + } + } + } + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 746ca3f4ef..56c2b43515 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -233,9 +233,11 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { token.addAbility(FlyingAbility.getInstance()); } if (tokenPower != Integer.MIN_VALUE) { + token.removePTCDA(); token.getPower().modifyBaseValue(tokenPower); } if (tokenToughness != Integer.MIN_VALUE) { + token.removePTCDA(); token.getToughness().modifyBaseValue(tokenToughness); } if (additionalSubType != null && !token.hasSubtype(additionalSubType, game)) { diff --git a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java index e7ae5d52af..dd46c9d9d7 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java @@ -119,6 +119,7 @@ class EternalizeEffect extends OneShotEffect { token.getSubtype(game).add(0, SubType.ZOMBIE); } token.getManaCost().clear(); + token.removePTCDA(); token.getPower().modifyBaseValue(4); token.getToughness().modifyBaseValue(4); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); diff --git a/Mage/src/main/java/mage/game/permanent/token/Token.java b/Mage/src/main/java/mage/game/permanent/token/Token.java index 55f23dacdd..57aced4814 100644 --- a/Mage/src/main/java/mage/game/permanent/token/Token.java +++ b/Mage/src/main/java/mage/game/permanent/token/Token.java @@ -310,8 +310,4 @@ public class Token extends MageObjectImpl { this.setExpansionSetCodeForImage(setCode); return true; } - - - - } From 93f01af87e22c572af93e854142847ef2d995858 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 13:51:52 -0400 Subject: [PATCH 14/68] fixed SOI block being incorrectly included in standard, removed unnecessary bans --- .../Mage.Deck.Constructed/src/mage/deck/Standard.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java index 4f2dd72c22..674c0d189e 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java @@ -73,9 +73,7 @@ public class Standard extends Constructed { } } banned.add("Aetherworks Marvel"); - banned.add("Emrakul, the Promised End"); banned.add("Felidar Guardian"); - banned.add("Reflector Mage"); banned.add("Smuggler's Copter"); } @@ -83,6 +81,6 @@ public class Standard extends Constructed { Calendar cal = Calendar.getInstance(); cal.setTime(set.getReleaseDate()); // Sets from fall block are normally released in September and January - return cal.get(Calendar.MONTH) > 8 || cal.get(Calendar.MONTH) < 2; + return cal.get(Calendar.MONTH) > 7 || cal.get(Calendar.MONTH) < 2; } } From 549103a2f02eb2707aa935066c26a602e9a1cc84 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 16:32:36 -0400 Subject: [PATCH 15/68] some more changes to CDA effects, tested and working correctly --- Mage.Sets/src/mage/cards/a/ApocalypseDemon.java | 14 +++++++------- Mage/src/main/java/mage/MageObject.java | 5 +---- Mage/src/main/java/mage/MageObjectImpl.java | 1 + .../main/java/mage/designations/Designation.java | 3 +++ .../src/main/java/mage/game/command/Commander.java | 3 +++ .../main/java/mage/game/stack/StackObjImpl.java | 3 +++ .../src/main/java/mage/game/stack/StackObject.java | 2 +- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java index d0c539f2fd..085df8bada 100644 --- a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java +++ b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java @@ -17,11 +17,11 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.target.common.TargetControlledPermanent; public class ApocalypseDemon extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("nother creature"); - - static { - filter.add(new CardTypePredicate(CardType.CREATURE)); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(new AnotherPredicate()); } @@ -37,10 +37,10 @@ public class ApocalypseDemon extends CardImpl { // At the beginning of your upkeep, tap Apocalypse Demon unless you sacrifice another creature. TapSourceUnlessPaysEffect tapEffect = new TapSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))); - tapEffect.setText("At the beginning of your upkeep, tap Apocalypse Demon unless you sacrifice another creature."); + tapEffect.setText("tap {this} unless you sacrifice another creature."); this.addAbility(new BeginningOfUpkeepTriggeredAbility(tapEffect, TargetController.YOU, false)); - } - + } + public ApocalypseDemon(final ApocalypseDemon apocalypseDemon) { super(apocalypseDemon); } diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index 9982250353..567b0dca0e 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -17,11 +17,8 @@ import mage.util.SubTypeList; import java.io.Serializable; import java.util.EnumSet; -import java.util.Iterator; import java.util.List; import java.util.UUID; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; public interface MageObject extends MageItem, Serializable { @@ -201,7 +198,7 @@ public interface MageObject extends MageItem, Serializable { TextPart addTextPart(TextPart textPart); - public void removePTCDA(); + void removePTCDA(); default void changeSubType(SubType fromSubType, SubType toSubType) { diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java index 44f5f42feb..879bb06b58 100644 --- a/Mage/src/main/java/mage/MageObjectImpl.java +++ b/Mage/src/main/java/mage/MageObjectImpl.java @@ -342,6 +342,7 @@ public abstract class MageObjectImpl implements MageObject { } } + @Override public void removePTCDA() { for (Iterator iter = this.getAbilities().iterator(); iter.hasNext();) { Ability ability = iter.next(); diff --git a/Mage/src/main/java/mage/designations/Designation.java b/Mage/src/main/java/mage/designations/Designation.java index e1ba4ab45a..7d3d842a9c 100644 --- a/Mage/src/main/java/mage/designations/Designation.java +++ b/Mage/src/main/java/mage/designations/Designation.java @@ -215,4 +215,7 @@ public abstract class Designation implements MageObject { throw new UnsupportedOperationException("Unsupported operation"); } + @Override + public void removePTCDA() { + } } diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java index b0ee9693df..7d7e0c9c6d 100644 --- a/Mage/src/main/java/mage/game/command/Commander.java +++ b/Mage/src/main/java/mage/game/command/Commander.java @@ -249,4 +249,7 @@ public class Commander implements CommandObject { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + @Override + public void removePTCDA() { + } } diff --git a/Mage/src/main/java/mage/game/stack/StackObjImpl.java b/Mage/src/main/java/mage/game/stack/StackObjImpl.java index 4f21e40ce1..25a3088eab 100644 --- a/Mage/src/main/java/mage/game/stack/StackObjImpl.java +++ b/Mage/src/main/java/mage/game/stack/StackObjImpl.java @@ -268,4 +268,7 @@ public abstract class StackObjImpl implements StackObject { return name; } + @Override + public void removePTCDA() { + } } diff --git a/Mage/src/main/java/mage/game/stack/StackObject.java b/Mage/src/main/java/mage/game/stack/StackObject.java index b90d5a7a2f..7268f9ab03 100644 --- a/Mage/src/main/java/mage/game/stack/StackObject.java +++ b/Mage/src/main/java/mage/game/stack/StackObject.java @@ -50,7 +50,7 @@ public interface StackObject extends MageObject, Controllable { // int getConvertedManaCost(); boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget, FilterPermanent filterNewTarget); - + StackObject createCopyOnStack(Game game, Ability source, UUID newControllerId, boolean chooseNewTargets); @Override From 67bc2fb6bb81a146810a9cc2e127e79e43f26d15 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 16:58:03 -0400 Subject: [PATCH 16/68] Updated some power-setting and toughness-setting effects to the correct layers --- .../src/mage/cards/a/ApocalypseDemon.java | 37 ++++++++++++++-- .../src/mage/cards/c/CraterElemental.java | 11 ++--- .../src/mage/cards/i/IslandOfWakWak.java | 4 +- Mage.Sets/src/mage/cards/s/Sentinel.java | 5 ++- Mage.Sets/src/mage/cards/s/SingingTree.java | 44 ++++++++++++++++--- .../continuous/SetPowerSourceEffect.java | 8 ++-- .../continuous/SetToughnessSourceEffect.java | 7 ++- 7 files changed, 93 insertions(+), 23 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java index 085df8bada..889d8d735c 100644 --- a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java +++ b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java @@ -1,3 +1,30 @@ +/* +* 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; @@ -16,9 +43,13 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; import mage.target.common.TargetControlledPermanent; +/** + * + * @author MajorLazar + */ public class ApocalypseDemon extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("nother creature"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another creature"); static { filter.add(new CardTypePredicate(CardType.CREATURE)); @@ -41,8 +72,8 @@ public class ApocalypseDemon extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(tapEffect, TargetController.YOU, false)); } - public ApocalypseDemon(final ApocalypseDemon apocalypseDemon) { - super(apocalypseDemon); + public ApocalypseDemon(final ApocalypseDemon card) { + super(card); } public ApocalypseDemon copy() { diff --git a/Mage.Sets/src/mage/cards/c/CraterElemental.java b/Mage.Sets/src/mage/cards/c/CraterElemental.java index a3df9319dd..935ac7afaa 100644 --- a/Mage.Sets/src/mage/cards/c/CraterElemental.java +++ b/Mage.Sets/src/mage/cards/c/CraterElemental.java @@ -45,6 +45,7 @@ import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubLayer; import mage.constants.Zone; import mage.target.common.TargetCreaturePermanent; @@ -55,7 +56,7 @@ import mage.target.common.TargetCreaturePermanent; public class CraterElemental extends CardImpl { public CraterElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(0); this.toughness = new MageInt(6); @@ -66,14 +67,14 @@ public class CraterElemental extends CardImpl { ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater. ability = new ActivateIfConditionActivatedAbility( - Zone.BATTLEFIELD, - new SetPowerSourceEffect(new StaticValue(8), Duration.EndOfTurn), + Zone.BATTLEFIELD, + new SetPowerSourceEffect(new StaticValue(8), Duration.EndOfTurn, SubLayer.SetPT_7b), new ManaCostsImpl("{2}{R}"), FormidableCondition.instance); - ability.setAbilityWord(AbilityWord.FORMIDABLE); + ability.setAbilityWord(AbilityWord.FORMIDABLE); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IslandOfWakWak.java b/Mage.Sets/src/mage/cards/i/IslandOfWakWak.java index fea3f88ec4..e027cfcc87 100644 --- a/Mage.Sets/src/mage/cards/i/IslandOfWakWak.java +++ b/Mage.Sets/src/mage/cards/i/IslandOfWakWak.java @@ -62,7 +62,7 @@ public class IslandOfWakWak extends CardImpl { public IslandOfWakWak(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - // {tap}: The power of target creature with flying becomes 0 until end of turn. + // {tap}: Target creature with flying has base power 0 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new IslandOfWakWakEffect(), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent(filterWithFlying)); this.addAbility(ability); @@ -82,7 +82,7 @@ class IslandOfWakWakEffect extends OneShotEffect { public IslandOfWakWakEffect() { super(Outcome.Detriment); - staticText = "The power of target creature with flying becomes 0 until end of turn"; + staticText = "Target creature with flying has base power 0 until end of turn."; } public IslandOfWakWakEffect(final IslandOfWakWakEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/Sentinel.java b/Mage.Sets/src/mage/cards/s/Sentinel.java index a8024fb19f..1c67461fe4 100644 --- a/Mage.Sets/src/mage/cards/s/Sentinel.java +++ b/Mage.Sets/src/mage/cards/s/Sentinel.java @@ -41,6 +41,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubLayer; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; @@ -58,7 +59,7 @@ import mage.target.common.TargetCreaturePermanent; public class Sentinel extends CardImpl { public Sentinel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(1); this.toughness = new MageInt(1); @@ -105,7 +106,7 @@ class SentinelEffect extends OneShotEffect { Permanent targetPermanent = game.getPermanentOrLKIBattlefield(targetPointer.getFirst(game, source)); if (controller != null && targetPermanent != null) { int newToughness = targetPermanent.getPower().getValue() + 1; - game.addEffect(new SetToughnessSourceEffect(new StaticValue(newToughness), Duration.Custom), source); + game.addEffect(new SetToughnessSourceEffect(new StaticValue(newToughness), Duration.Custom, SubLayer.SetPT_7b), source); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/s/SingingTree.java b/Mage.Sets/src/mage/cards/s/SingingTree.java index e73405886a..c17e3ffa9a 100644 --- a/Mage.Sets/src/mage/cards/s/SingingTree.java +++ b/Mage.Sets/src/mage/cards/s/SingingTree.java @@ -32,14 +32,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; 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.common.TargetAttackingCreature; /** @@ -47,16 +51,16 @@ import mage.target.common.TargetAttackingCreature; * @author MarcoMarin */ public class SingingTree extends CardImpl { - + public SingingTree(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.PLANT); this.power = new MageInt(0); this.toughness = new MageInt(3); // {tap}: Target attacking creature's power becomes 0 until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SetPowerSourceEffect(new StaticValue(0), Duration.EndOfTurn), new TapSourceCost()); - ability.addTarget(new TargetAttackingCreature(1)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SingingTreeEffect(), new TapSourceCost()); + ability.addTarget(new TargetAttackingCreature()); this.addAbility(ability); } @@ -69,3 +73,31 @@ public class SingingTree extends CardImpl { return new SingingTree(this); } } + +class SingingTreeEffect extends OneShotEffect { + + public SingingTreeEffect() { + super(Outcome.Detriment); + staticText = "Target attacking creature has base power 0 until end of turn."; + } + + public SingingTreeEffect(final SingingTreeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(source.getFirstTarget()); + if (targetCreature != null) { + int toughness = targetCreature.getToughness().getBaseValueModified(); + game.addEffect(new SetPowerToughnessTargetEffect(0, toughness, Duration.EndOfTurn), source); + return true; + } + return false; + } + + @Override + public Effect copy() { + return new SingingTreeEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerSourceEffect.java index dbafe0c94b..c344149b8d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerSourceEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.continuous; import mage.MageObject; @@ -42,13 +41,16 @@ import mage.game.Game; * * @author LevelX2 */ - public class SetPowerSourceEffect extends ContinuousEffectImpl { private final DynamicValue amount; public SetPowerSourceEffect(DynamicValue amount, Duration duration) { - super(duration, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature); + this(amount, duration, SubLayer.CharacteristicDefining_7a); + } + + public SetPowerSourceEffect(DynamicValue amount, Duration duration, SubLayer subLayer) { + super(duration, Layer.PTChangingEffects_7, subLayer, Outcome.BoostCreature); this.amount = amount; staticText = "{this}'s power is equal to the number of " + amount.getMessage(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetToughnessSourceEffect.java index af48b2b92c..b539625c80 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetToughnessSourceEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.continuous; import mage.MageObject; @@ -46,7 +45,11 @@ public class SetToughnessSourceEffect extends ContinuousEffectImpl { private final DynamicValue amount; public SetToughnessSourceEffect(DynamicValue amount, Duration duration) { - super(duration, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature); + this(amount, duration, SubLayer.CharacteristicDefining_7a); + } + + public SetToughnessSourceEffect(DynamicValue amount, Duration duration, SubLayer subLayer) { + super(duration, Layer.PTChangingEffects_7, subLayer, Outcome.BoostCreature); this.amount = amount; staticText = "{this}'s toughness is equal to the number of " + amount.getMessage(); } From b4302fb01cd6ae723d1fd7e1233dea77506bc06c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 17:37:02 -0400 Subject: [PATCH 17/68] fixed Overbeing of Myth's power/toughness outside the battlefield --- Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java b/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java index 0a0e2e4103..4d00a37f8f 100644 --- a/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java +++ b/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java @@ -46,12 +46,12 @@ import mage.constants.Zone; /** * * @author jeffwadsworth - + * */ public class OverbeingOfMyth extends CardImpl { public OverbeingOfMyth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G/U}{G/U}{G/U}{G/U}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G/U}{G/U}{G/U}{G/U}{G/U}"); this.subtype.add(SubType.SPIRIT); this.subtype.add(SubType.AVATAR); @@ -60,11 +60,11 @@ public class OverbeingOfMyth extends CardImpl { // Overbeing of Myth's power and toughness are each equal to the number of cards in your hand. DynamicValue number = new CardsInControllerHandCount(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetPowerToughnessSourceEffect(number, Duration.WhileOnBattlefield))); - + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(number, Duration.EndOfGame))); + // At the beginning of your draw step, draw an additional card. this.addAbility(new BeginningOfDrawTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false)); - + } public OverbeingOfMyth(final OverbeingOfMyth card) { From ced243df0a5cc13508ac4668c21eecbfae2ac64e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 19:36:48 -0400 Subject: [PATCH 18/68] fixed Aethergeode Miner and Flickering Spirit returning to the battlefield even if they die before their abilities resolve --- .../src/mage/cards/a/AethergeodeMiner.java | 42 ++++++++++++++-- .../src/mage/cards/f/FlickeringSpirit.java | 48 +++++++++++++++---- 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AethergeodeMiner.java b/Mage.Sets/src/mage/cards/a/AethergeodeMiner.java index 7e1851384b..60912dd97b 100644 --- a/Mage.Sets/src/mage/cards/a/AethergeodeMiner.java +++ b/Mage.Sets/src/mage/cards/a/AethergeodeMiner.java @@ -33,14 +33,17 @@ import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.PayEnergyCost; -import mage.abilities.effects.common.ExileSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlSourceEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect; +import mage.cards.Card; 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.game.Game; +import mage.game.permanent.Permanent; /** * @@ -60,9 +63,7 @@ public class AethergeodeMiner extends CardImpl { this.addAbility(new AttacksTriggeredAbility(new GetEnergyCountersControllerEffect(2), false)); // Pay {E}{E}: Exile Aethergeode Miner, then return it to the battlefield under its owner's control. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(true), new PayEnergyCost(2)); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlSourceEffect()); - this.addAbility(ability); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AethergeodeMinerEffect(), new PayEnergyCost(2))); } public AethergeodeMiner(final AethergeodeMiner card) { @@ -74,3 +75,34 @@ public class AethergeodeMiner extends CardImpl { return new AethergeodeMiner(this); } } + +class AethergeodeMinerEffect extends OneShotEffect { + + public AethergeodeMinerEffect() { + super(Outcome.Neutral); + this.staticText = "Exile {this}, then return it to the battlefield under its owner's control"; + } + + public AethergeodeMinerEffect(final AethergeodeMinerEffect effect) { + super(effect); + } + + @Override + public AethergeodeMinerEffect copy() { + return new AethergeodeMinerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + if (permanent.moveToExile(source.getSourceId(), "Aethergeode Miner", source.getSourceId(), game)) { + Card card = game.getExile().getCard(source.getSourceId(), game); + if (card != null) { + return card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlickeringSpirit.java b/Mage.Sets/src/mage/cards/f/FlickeringSpirit.java index 3a9622f0b9..442e307844 100644 --- a/Mage.Sets/src/mage/cards/f/FlickeringSpirit.java +++ b/Mage.Sets/src/mage/cards/f/FlickeringSpirit.java @@ -32,14 +32,17 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlSourceEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; 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.game.Game; +import mage.game.permanent.Permanent; /** * @@ -48,19 +51,17 @@ import mage.constants.Zone; public class FlickeringSpirit extends CardImpl { public FlickeringSpirit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); this.toughness = new MageInt(2); // Flying this.addAbility(FlyingAbility.getInstance()); - + // {3}{W}: Exile Flickering Spirit, then return it to the battlefield under its owner's control. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(true), new ManaCostsImpl("{3}{W}")); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlSourceEffect()); - this.addAbility(ability); - + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new FlickeringSpiritEffect(), new ManaCostsImpl("{3}{W}"))); + } public FlickeringSpirit(final FlickeringSpirit card) { @@ -72,3 +73,34 @@ public class FlickeringSpirit extends CardImpl { return new FlickeringSpirit(this); } } + +class FlickeringSpiritEffect extends OneShotEffect { + + public FlickeringSpiritEffect() { + super(Outcome.Neutral); + this.staticText = "Exile {this}, then return it to the battlefield under its owner's control"; + } + + public FlickeringSpiritEffect(final FlickeringSpiritEffect effect) { + super(effect); + } + + @Override + public FlickeringSpiritEffect copy() { + return new FlickeringSpiritEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + if (permanent.moveToExile(source.getSourceId(), "Flickering Spirit", source.getSourceId(), game)) { + Card card = game.getExile().getCard(source.getSourceId(), game); + if (card != null) { + return card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); + } + } + } + return false; + } +} From de8ae96aaa33d4c2b77800e0f9e19428082e8ad7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 20:55:02 -0400 Subject: [PATCH 19/68] Fixed Hour of Eternity's targeting and another small fix that was causing an error --- Mage.Sets/src/mage/cards/h/HourOfEternity.java | 12 ++++++++++++ Mage/src/main/java/mage/game/command/Emblem.java | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/h/HourOfEternity.java b/Mage.Sets/src/mage/cards/h/HourOfEternity.java index 813a8b3293..51c6c012fe 100644 --- a/Mage.Sets/src/mage/cards/h/HourOfEternity.java +++ b/Mage.Sets/src/mage/cards/h/HourOfEternity.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; +import mage.abilities.SpellAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -44,6 +45,7 @@ import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.token.EmptyToken; import mage.players.Player; +import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; import mage.util.CardUtil; @@ -61,6 +63,16 @@ public class HourOfEternity extends CardImpl { this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard"))); } + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + Target target = new TargetCardInYourGraveyard(xValue, new FilterCreatureCard(new StringBuilder(xValue).append(xValue != 1 ? " creature cards" : "creature card").append(" from your graveyard").toString())); + ability.addTarget(target); + } + } + public HourOfEternity(final HourOfEternity card) { super(card); } diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java index 2af44f81e5..85d6fe8d9a 100644 --- a/Mage/src/main/java/mage/game/command/Emblem.java +++ b/Mage/src/main/java/mage/game/command/Emblem.java @@ -59,7 +59,6 @@ import mage.util.SubTypeList; public class Emblem implements CommandObject { private static EnumSet emptySet = EnumSet.noneOf(CardType.class); - private static List emptyList = new ArrayList(); private static ObjectColor emptyColor = new ObjectColor(); private static ManaCosts emptyCost = new ManaCostsImpl(); @@ -297,4 +296,7 @@ public class Emblem implements CommandObject { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + @Override + public void removePTCDA() { + } } From a110b54d91b07c631a0f41dcbb2e8c1f9610301c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 2 Oct 2017 21:23:43 -0400 Subject: [PATCH 20/68] Setting Mage Verify to ignore until mtgjson is updated with the latest oracle text --- Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index e715c8bfef..bf06ef019e 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -16,6 +16,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.junit.Ignore; public class VerifyCardDataTest { @@ -48,6 +49,7 @@ public class VerifyCardDataTest { private int failed = 0; + @Ignore @Test public void verifyCards() throws IOException { for (Card card : allCards()) { @@ -152,7 +154,7 @@ public class VerifyCardDataTest { Collection expected = ref.subtypes; if (expected != null && expected.contains("Urza’s")) { expected = new ArrayList<>(expected); - for (ListIterator it = ((List) expected).listIterator(); it.hasNext(); ) { + for (ListIterator it = ((List) expected).listIterator(); it.hasNext();) { if (it.next().equals("Urza’s")) { it.set("Urza's"); } From 9cbc2b7ea204c8ea42fff2bfe49ee954b9f7f15d Mon Sep 17 00:00:00 2001 From: igoudt Date: Tue, 3 Oct 2017 15:18:31 +0200 Subject: [PATCH 21/68] change client messages to enum rather than string --- .../main/java/mage/client/cards/CardArea.java | 32 +++-- .../mage/client/cards/CardEventSource.java | 43 ++----- .../main/java/mage/client/cards/CardGrid.java | 29 ++--- .../java/mage/client/cards/CardsList.java | 91 +++++++------- .../java/mage/client/cards/DraftGrid.java | 18 +-- .../java/mage/client/cards/DragCardGrid.java | 14 +-- .../java/mage/client/deckeditor/DeckArea.java | 14 ++- .../client/deckeditor/DeckEditorPanel.java | 83 ++++++------- .../client/deckeditor/table/TableModel.java | 13 +- .../java/mage/client/draft/DraftPanel.java | 66 ++++------ .../main/java/mage/client/game/GamePanel.java | 115 ++++-------------- .../client/table/PlayerTypeEventSource.java | 8 +- .../mage/client/util/ClientEventType.java | 20 +++ .../src/main/java/mage/client/util/Event.java | 18 +-- 14 files changed, 233 insertions(+), 331 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/util/ClientEventType.java diff --git a/Mage.Client/src/main/java/mage/client/cards/CardArea.java b/Mage.Client/src/main/java/mage/client/cards/CardArea.java index e14e810134..5fa3840253 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardArea.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardArea.java @@ -27,20 +27,9 @@ */ package mage.client.cards; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.List; -import java.util.UUID; -import javax.swing.JLayeredPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; import mage.cards.MageCard; import mage.client.plugins.impl.Plugins; +import mage.client.util.ClientEventType; import mage.client.util.Event; import mage.client.util.GUISizeHelper; import mage.client.util.Listener; @@ -50,6 +39,13 @@ import mage.view.CardsView; import mage.view.SimpleCardView; import org.mage.card.arcane.CardPanel; +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.List; +import java.util.UUID; + public class CardArea extends JPanel implements MouseListener { protected final CardEventSource cardEventSource = new CardEventSource(); @@ -240,15 +236,15 @@ public class CardArea extends JPanel implements MouseListener { e.consume(); if (obj instanceof Card) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((Card) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((Card) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK); } } else if (obj instanceof MageCard) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((MageCard) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((MageCard) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(),ClientEventType.DOUBLE_CLICK); } } } @@ -270,14 +266,14 @@ public class CardArea extends JPanel implements MouseListener { checkMenu(e, null); } } else { - cardEventSource.actionConsumedEvent("action-consumed"); + cardEventSource.fireEvent(ClientEventType.ACTION_CONSUMED); } } private void checkMenu(MouseEvent Me, SimpleCardView card) { if (Me.isPopupTrigger()) { Me.consume(); - cardEventSource.showPopupMenuEvent(card, Me.getComponent(), Me.getX(), Me.getY(), "show-popup-menu"); + cardEventSource.fireEvent(card, Me.getComponent(), Me.getX(), Me.getY(), ClientEventType.SHOW_POP_UP_MENU); } } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java index 81e29d83db..fb7282a4a3 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java @@ -27,14 +27,13 @@ */ package mage.client.cards; -import java.awt.Component; -import java.io.Serializable; +import mage.client.util.*; import mage.client.util.Event; -import mage.client.util.EventDispatcher; -import mage.client.util.EventSource; -import mage.client.util.Listener; import mage.view.SimpleCardView; +import java.awt.*; +import java.io.Serializable; + /** * * @author BetaSteward_at_googlemail.com @@ -49,42 +48,22 @@ public class CardEventSource implements EventSource, Serializable { dispatcher.addListener(listener); } - public void setNumber(SimpleCardView card, String message, int number) { - dispatcher.fireEvent(new Event(card, message, number)); + public void fireEvent(SimpleCardView card, ClientEventType eventType, int number){ + dispatcher.fireEvent(new Event(card, eventType, number)); } - public void removeSpecificCard(SimpleCardView card, String message) { - dispatcher.fireEvent(new Event(card, message)); + public void fireEvent(ClientEventType eventType){ + dispatcher.fireEvent(new Event(null, eventType)); } - public void addSpecificCard(SimpleCardView card, String message) { - dispatcher.fireEvent(new Event(card, message)); + public void fireEvent(SimpleCardView card, ClientEventType eventType){ + dispatcher.fireEvent(new Event(card, eventType)); } - public void doubleClick(SimpleCardView card, String message) { - dispatcher.fireEvent(new Event(card, message)); - } - - public void altDoubleClick(SimpleCardView card, String message) { - dispatcher.fireEvent(new Event(card, message)); - } - - public void removeFromMainEvent(String message) { - dispatcher.fireEvent(new Event(null, message)); - } - - public void removeFromSideboardEvent(String message) { - dispatcher.fireEvent(new Event(null, message)); - } - - public void showPopupMenuEvent(SimpleCardView card, Component component, int x, int y, String message) { + public void fireEvent(SimpleCardView card, Component component, int x, int y, ClientEventType message) { dispatcher.fireEvent(new Event(card, message, x, y, component)); } - public void actionConsumedEvent(String message) { - dispatcher.fireEvent(new Event(null, message)); - } - @Override public void clearListeners() { dispatcher.clearListeners(); diff --git a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java index dbf4c1d6da..fe918f797d 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java @@ -33,22 +33,10 @@ */ package mage.client.cards; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; import mage.cards.MageCard; import mage.client.deckeditor.SortSetting; import mage.client.plugins.impl.Plugins; +import mage.client.util.ClientEventType; import mage.client.util.Event; import mage.client.util.GUISizeHelper; import mage.client.util.Listener; @@ -57,6 +45,13 @@ import mage.view.CardView; import mage.view.CardsView; import org.mage.card.arcane.CardPanel; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.*; +import java.util.List; +import java.util.Map.Entry; + /** * * @author BetaSteward_at_googlemail.com @@ -321,15 +316,15 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, Object obj = e.getSource(); if (obj instanceof Card) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((Card) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((Card) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK); } } else if (obj instanceof MageCard) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((MageCard) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((MageCard) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.DOUBLE_CLICK); } } } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.java b/Mage.Client/src/main/java/mage/client/cards/CardsList.java index 637271efa5..aca7e83919 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -62,7 +62,6 @@ import java.util.*; import java.util.List; /** - * * @author BetaSteward_at_googlemail.com */ public class CardsList extends javax.swing.JPanel implements MouseListener, ICardGrid { @@ -475,9 +474,9 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); setMinimumSize(new java.awt.Dimension(30, 30)); - setPreferredSize((!Beans.isDesignTime())? - (GUISizeHelper.editorCardDimension) - :(new Dimension(600, 600))); + setPreferredSize((!Beans.isDesignTime()) ? + (GUISizeHelper.editorCardDimension) + : (new Dimension(600, 600))); setRequestFocusEnabled(false); panelControl.setMaximumSize(new java.awt.Dimension(32767, 23)); @@ -522,7 +521,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar chkPiles.setMargin(new java.awt.Insets(3, 2, 2, 2)); chkPiles.addActionListener(evt -> chkPilesActionPerformed(evt)); - cbSortBy.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "SortBy" })); + cbSortBy.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"SortBy"})); cbSortBy.setToolTipText("Sort the cards if card view is active."); cbSortBy.setMaximumSize(new java.awt.Dimension(120, 20)); cbSortBy.setMinimumSize(new java.awt.Dimension(120, 20)); @@ -553,36 +552,36 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar javax.swing.GroupLayout panelControlLayout = new javax.swing.GroupLayout(panelControl); panelControl.setLayout(panelControlLayout); panelControlLayout.setHorizontalGroup( - panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createSequentialGroup() - .addComponent(lblCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblLandCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblCreatureCount) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkPiles) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addComponent(lblCount) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblLandCount) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblCreatureCount) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkPiles) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelControlLayout.setVerticalGroup( - panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createSequentialGroup() - .addGroup(panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lblCount) - .addComponent(lblLandCount) - .addComponent(lblCreatureCount) - .addComponent(chkPiles)) - .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0)) + panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addGroup(panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblCount) + .addComponent(lblLandCount) + .addComponent(lblCreatureCount) + .addComponent(chkPiles)) + .addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jToggleListView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jToggleCardView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) ); jToggleListView.getAccessibleContext().setAccessibleDescription("Switch between image and table view."); @@ -593,16 +592,16 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, 467, Short.MAX_VALUE) - .addComponent(panelCardArea) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, 467, Short.MAX_VALUE) + .addComponent(panelCardArea) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(2, 2, 2) - .addComponent(panelCardArea, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(panelControl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addComponent(panelCardArea, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -660,15 +659,15 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar e.consume(); if (obj instanceof Card) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((Card) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((Card) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK); } } else if (obj instanceof MageCard) { if (e.isAltDown()) { - cardEventSource.altDoubleClick(((MageCard) obj).getOriginal(), "alt-double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK); } else { - cardEventSource.doubleClick(((MageCard) obj).getOriginal(), "double-click"); + cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.DOUBLE_CLICK); } } } @@ -695,7 +694,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar private void checkMenu(MouseEvent Me, SimpleCardView card) { if (Me.isPopupTrigger()) { Me.consume(); - cardEventSource.showPopupMenuEvent(card, Me.getComponent(), Me.getX(), Me.getY(), "show-popup-menu"); + cardEventSource.fireEvent(card, Me.getComponent(), Me.getX(), Me.getY(), ClientEventType.SHOW_POP_UP_MENU); } } diff --git a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java index dc91515619..409a0ac273 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java @@ -34,17 +34,11 @@ package mage.client.cards; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.List; import mage.cards.CardDimensions; import mage.cards.MageCard; import mage.client.plugins.impl.Plugins; import mage.client.util.CardViewRarityComparator; +import mage.client.util.ClientEventType; import mage.client.util.Event; import mage.client.util.Listener; import mage.client.util.audio.AudioManager; @@ -53,6 +47,12 @@ import mage.view.CardView; import mage.view.CardsView; import org.apache.log4j.Logger; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; + /** * * @author BetaSteward_at_googlemail.com @@ -186,7 +186,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener { if (e.getButton() == MouseEvent.BUTTON1) { Object obj = e.getSource(); if (obj instanceof MageCard) { - this.cardEventSource.doubleClick(((MageCard)obj).getOriginal(), "pick-a-card"); + this.cardEventSource.fireEvent(((MageCard)obj).getOriginal(), ClientEventType.PICK_A_CARD); this.hidePopup(); AudioManager.playOnDraftSelect(); } @@ -203,7 +203,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener { if (this.markedCard != null) { markedCard.setSelected(false); } - this.cardEventSource.doubleClick(((MageCard)obj).getOriginal(), "mark-a-card"); + this.cardEventSource.fireEvent(((MageCard)obj).getOriginal(), ClientEventType.MARK_A_CARD); markedCard = ((MageCard)obj); markedCard.setSelected(true); repaint(); diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index 6973fa4ea7..c93f0fecb9 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -70,7 +70,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg if (card.isSelected()) { stack.set(i, null); removeCardView(card); - eventSource.removeSpecificCard(card, "remove-specific-card"); + eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD); } } } @@ -326,7 +326,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg for (CardView card : cards) { card.setSelected(true); addCardView(card, false); - eventSource.addSpecificCard(card, "add-specific-card"); + eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD); } layoutGrid(); cardContent.repaint(); @@ -381,7 +381,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg for (int i = 0; i < stack.size(); ++i) { CardView card = stack.get(i); if (card.isSelected()) { - eventSource.removeSpecificCard(card, "remove-specific-card"); + eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD); stack.set(i, null); removeCardView(card); } @@ -1497,7 +1497,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg if (acard.getName().equals(card.getName())) { CardView pimpedCard = new CardView(acard); addCardView(pimpedCard, false); - eventSource.addSpecificCard(pimpedCard, "add-specific-card"); + eventSource.fireEvent(pimpedCard, ClientEventType.ADD_SPECIFIC_CARD); pimpedCards.put(pimpedCard, 1); didModify = true; } @@ -1748,9 +1748,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg if (e.getClickCount() == 1) { cardClicked(card, e); } else if (e.isAltDown()) { - eventSource.altDoubleClick(card, "alt-double-click"); + eventSource.fireEvent(card, ClientEventType.ALT_DOUBLE_CLICK); } else { - eventSource.doubleClick(card, "double-click"); + eventSource.fireEvent(card, ClientEventType.DOUBLE_CLICK); } } } @@ -1776,7 +1776,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg if (duplicated) { sortIntoGrid(card); - eventSource.addSpecificCard(card, "add-specific-card"); + eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD); // Update layout layoutGrid(); // Update draw diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java index 64fdad5015..0ccbbee26a 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java @@ -32,10 +32,6 @@ */ package mage.client.deckeditor; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.swing.*; import mage.cards.Card; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLayout; @@ -43,12 +39,18 @@ import mage.client.cards.BigCard; import mage.client.cards.CardEventSource; import mage.client.cards.DragCardGrid; import mage.client.constants.Constants.DeckEditorMode; +import mage.client.util.ClientEventType; import mage.client.util.Event; import mage.client.util.GUISizeHelper; import mage.client.util.Listener; import mage.view.CardView; import mage.view.CardsView; +import javax.swing.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * * @author BetaSteward_at_googlemail.com @@ -124,8 +126,8 @@ public class DeckArea extends javax.swing.JPanel { // Add to hidden and move to sideboard for (CardView card : cards) { hiddenCards.add(card.getId()); - maindeckVirtualEvent.removeSpecificCard(card, "remove-specific-card"); - sideboardVirtualEvent.addSpecificCard(card, "add-specific-card"); + maindeckVirtualEvent.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD); + sideboardVirtualEvent.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD); } loadDeck(lastDeck, lastBigCard); } diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index f2b93ca6ec..b7ae78ced5 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -27,23 +27,6 @@ */ package mage.client.deckeditor; -import java.awt.*; -import java.awt.event.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.*; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import javax.swing.*; -import javax.swing.Timer; -import javax.swing.filechooser.FileFilter; import mage.cards.Card; import mage.cards.Sets; import mage.cards.decks.Deck; @@ -72,6 +55,18 @@ import mage.view.CardView; import mage.view.SimpleCardView; import org.apache.log4j.Logger; +import javax.swing.*; +import javax.swing.Timer; +import javax.swing.filechooser.FileFilter; +import java.awt.*; +import java.awt.event.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.*; +import java.util.List; +import java.util.concurrent.*; + /** * @author BetaSteward_at_googlemail.com */ @@ -280,11 +275,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { component.clearCardEventListeners(); component.addCardEventListener( (Listener) event -> { - switch (event.getEventName()) { - case "double-click": + switch (event.getEventType()) { + case DOUBLE_CLICK: moveSelectorCardToDeck(event); break; - case "alt-double-click": + case ALT_DOUBLE_CLICK: if (mode == DeckEditorMode.FREE_BUILDING) { moveSelectorCardToSideboard(event); } else { @@ -292,10 +287,10 @@ public class DeckEditorPanel extends javax.swing.JPanel { moveSelectorCardToDeck(event); } break; - case "remove-main": + case REMOVE_MAIN: DeckEditorPanel.this.deckArea.getDeckList().removeSelection(); break; - case "remove-sideboard": + case REMOVE_SIDEBOARD: DeckEditorPanel.this.deckArea.getSideboardList().removeSelection(); break; } @@ -306,8 +301,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.deckArea.addDeckEventListener( (Listener) event -> { if (mode == DeckEditorMode.FREE_BUILDING) { - switch (event.getEventName()) { - case "double-click": { + switch (event.getEventType()) { + case DOUBLE_CLICK: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { @@ -319,7 +314,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { refreshDeck(); break; } - case "alt-double-click": { + case ALT_DOUBLE_CLICK: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { @@ -332,11 +327,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { refreshDeck(); break; } - case "set-number": { + case SET_NUMBER: { setCardNumberToCardsList(event, deck.getCards()); break; } - case "remove-specific-card": { + case REMOVE_SPECIFIC_CARD: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { @@ -347,7 +342,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } break; } - case "add-specific-card": { + case ADD_SPECIFIC_CARD: { SimpleCardView cardView = (CardView) event.getSource(); deck.getCards().add(retrieveTemporaryCard(cardView)); break; @@ -355,9 +350,9 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } else { // constructing phase or sideboarding during match -> card goes always to sideboard - switch (event.getEventName()) { - case "double-click": - case "alt-double-click": { + switch (event.getEventType()) { + case DOUBLE_CLICK: + case ALT_DOUBLE_CLICK: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { @@ -371,7 +366,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { refreshDeck(); break; } - case "remove-specific-card": { + case REMOVE_SPECIFIC_CARD: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { @@ -382,7 +377,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } break; } - case "add-specific-card": { + case ADD_SPECIFIC_CARD: { SimpleCardView cardView = (CardView) event.getSource(); deck.getCards().add(retrieveTemporaryCard(cardView)); break; @@ -395,8 +390,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { (Listener) event -> { if (mode == DeckEditorMode.FREE_BUILDING) { // normal edit mode - switch (event.getEventName()) { - case "double-click": + switch (event.getEventType()) { + case DOUBLE_CLICK: // remove card from sideboard (don't add it to deck) SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getSideboard()) { @@ -408,7 +403,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { hidePopup(); refreshDeck(); break; - case "alt-double-click": + case ALT_DOUBLE_CLICK: // remove card from sideboard cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getSideboard()) { @@ -421,11 +416,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { hidePopup(); refreshDeck(); break; - case "set-number": { + case SET_NUMBER: { setCardNumberToCardsList(event, deck.getSideboard()); break; } - case "remove-specific-card": { + case REMOVE_SPECIFIC_CARD: { cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getSideboard()) { if (card.getId().equals(cardView.getId())) { @@ -436,7 +431,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } break; } - case "add-specific-card": { + case ADD_SPECIFIC_CARD: { cardView = (CardView) event.getSource(); deck.getSideboard().add(retrieveTemporaryCard(cardView)); break; @@ -444,8 +439,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } else { // construct phase or sideboarding during match - switch (event.getEventName()) { - case "remove-specific-card": { + switch (event.getEventType()) { + case REMOVE_SPECIFIC_CARD: { SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getSideboard()) { if (card.getId().equals(cardView.getId())) { @@ -456,13 +451,13 @@ public class DeckEditorPanel extends javax.swing.JPanel { } break; } - case "add-specific-card": { + case ADD_SPECIFIC_CARD: { SimpleCardView cardView = (CardView) event.getSource(); deck.getSideboard().add(retrieveTemporaryCard(cardView)); break; } - case "double-click": - case "alt-double-click": + case DOUBLE_CLICK: + case ALT_DOUBLE_CLICK: SimpleCardView cardView = (SimpleCardView) event.getSource(); for (Card card : deck.getSideboard()) { if (card.getId().equals(cardView.getId())) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java b/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java index cc54162334..44ed87185b 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java @@ -33,6 +33,7 @@ import mage.client.cards.CardEventSource; import mage.client.cards.ICardGrid; import mage.client.deckeditor.SortSetting; import mage.client.plugins.impl.Plugins; +import mage.client.util.ClientEventType; import mage.client.util.Config; import mage.client.util.Event; import mage.client.util.Listener; @@ -146,7 +147,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid { } // no easy logic for merge :) - for (Iterator> i = cards.entrySet().iterator(); i.hasNext();) { + for (Iterator> i = cards.entrySet().iterator(); i.hasNext(); ) { Entry entry = i.next(); if (!showCards.containsKey(entry.getKey())) { i.remove(); @@ -306,25 +307,25 @@ public class TableModel extends AbstractTableModel implements ICardGrid { public void setNumber(int index, int number) { CardView card = view.get(index); - cardEventSource.setNumber(card, "set-number", number); + cardEventSource.fireEvent(card, ClientEventType.SET_NUMBER, number); } public void doubleClick(int index) { CardView card = view.get(index); - cardEventSource.doubleClick(card, "double-click"); + cardEventSource.fireEvent(card, ClientEventType.DOUBLE_CLICK); } public void altDoubleClick(int index) { CardView card = view.get(index); - cardEventSource.altDoubleClick(card, "alt-double-click"); + cardEventSource.fireEvent(card, ClientEventType.ALT_DOUBLE_CLICK); } public void removeFromMainEvent(int index) { - cardEventSource.removeFromMainEvent("remove-main"); + cardEventSource.fireEvent(ClientEventType.REMOVE_MAIN); } public void removeFromSideEvent(int index) { - cardEventSource.removeFromSideboardEvent("remove-sideboard"); + cardEventSource.fireEvent(ClientEventType.REMOVE_SIDEBOARD); } public void addListeners(final JTable table) { diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 56b22b9b38..a5322b4f52 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -33,9 +33,25 @@ */ package mage.client.draft; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Image; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.client.MageFrame; +import mage.client.SessionHandler; +import mage.client.components.tray.MageTray; +import mage.client.deckeditor.SortSettingDraft; +import mage.client.dialog.PreferencesDialog; +import mage.client.plugins.impl.Plugins; +import mage.client.util.*; +import mage.client.util.Event; +import mage.client.util.audio.AudioManager; +import mage.client.util.gui.BufferedImageBuilder; +import mage.constants.PlayerAction; +import mage.view.*; +import org.apache.log4j.Logger; + +import javax.swing.*; +import javax.swing.Timer; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; @@ -46,43 +62,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import javax.swing.AbstractAction; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; -import javax.swing.KeyStroke; -import javax.swing.Timer; -import mage.cards.repository.CardInfo; -import mage.cards.repository.CardRepository; -import mage.client.MageFrame; -import mage.client.SessionHandler; -import mage.client.components.tray.MageTray; -import mage.client.deckeditor.SortSettingDraft; -import mage.client.dialog.PreferencesDialog; -import mage.client.plugins.impl.Plugins; -import mage.client.util.CardsViewUtil; -import mage.client.util.Event; -import mage.client.util.GUISizeHelper; -import mage.client.util.ImageHelper; -import mage.client.util.Listener; -import mage.client.util.audio.AudioManager; -import mage.client.util.gui.BufferedImageBuilder; -import mage.constants.PlayerAction; -import mage.view.CardsView; -import mage.view.DraftPickView; -import mage.view.DraftView; -import mage.view.SimpleCardView; -import mage.view.SimpleCardsView; -import mage.view.UserRequestMessage; -import org.apache.log4j.Logger; +import java.util.*; /** * @@ -304,7 +284,7 @@ public class DraftPanel extends javax.swing.JPanel { this.draftPicks.clearCardEventListeners(); this.draftPicks.addCardEventListener((Listener) event -> { - if (event.getEventName().equals("show-popup-menu")) { + if (event.getEventType() == ClientEventType.SHOW_POP_UP_MENU) { if (event.getSource() != null) { // Popup Menu Card cardIdPopupMenu = ((SimpleCardView) event.getSource()).getId(); @@ -322,7 +302,7 @@ public class DraftPanel extends javax.swing.JPanel { this.draftBooster.clearCardEventListeners(); this.draftBooster.addCardEventListener( (Listener) event -> { - if (event.getEventName().equals("pick-a-card")) { + if (event.getEventType() == ClientEventType.PICK_A_CARD) { SimpleCardView source = (SimpleCardView) event.getSource(); DraftPickView view = SessionHandler.sendCardPick(draftId, source.getId(), cardsHidden); if (view != null) { @@ -332,7 +312,7 @@ public class DraftPanel extends javax.swing.JPanel { setMessage("Waiting for other players"); } } - if (event.getEventName().equals("mark-a-card")) { + if (event.getEventType() == ClientEventType.MARK_A_CARD) { SimpleCardView source = (SimpleCardView) event.getSource(); SessionHandler.sendCardMark(draftId, source.getId()); } diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index c215382b40..a014167df0 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -27,61 +27,6 @@ */ package mage.client.game; -import java.awt.AWTEvent; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import static java.awt.Component.LEFT_ALIGNMENT; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; -import javax.swing.GroupLayout.Alignment; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JLayeredPane; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; -import javax.swing.Timer; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; -import javax.swing.border.LineBorder; -import javax.swing.plaf.basic.BasicSplitPaneDivider; -import javax.swing.plaf.basic.BasicSplitPaneUI; import mage.cards.Card; import mage.cards.action.ActionCallback; import mage.choices.Choice; @@ -95,51 +40,43 @@ import mage.client.components.KeyboundButton; import mage.client.components.MageComponents; import mage.client.components.ext.dlg.DialogManager; import mage.client.components.layout.RelativeLayout; -import mage.client.dialog.CardInfoWindowDialog; +import mage.client.dialog.*; import mage.client.dialog.CardInfoWindowDialog.ShowType; -import mage.client.dialog.PickChoiceDialog; -import mage.client.dialog.PickNumberDialog; -import mage.client.dialog.PickPileDialog; -import mage.client.dialog.PreferencesDialog; -import static mage.client.dialog.PreferencesDialog.*; -import mage.client.dialog.ShowCardsDialog; import mage.client.game.FeedbackPanel.FeedbackMode; import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.impl.Plugins; -import mage.client.util.CardsViewUtil; +import mage.client.util.*; import mage.client.util.Event; -import mage.client.util.GUISizeHelper; -import mage.client.util.GameManager; -import mage.client.util.Listener; import mage.client.util.audio.AudioManager; import mage.client.util.gui.ArrowBuilder; import mage.client.util.gui.MageDialogState; -import mage.constants.Constants; -import mage.constants.EnlargeMode; -import mage.constants.PhaseStep; -import mage.constants.PlayerAction; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_FIRST; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_LAST; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_FIRST; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_LAST; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; -import mage.constants.Zone; +import mage.constants.*; import mage.game.events.PlayerQueryEvent; -import mage.view.AbilityPickerView; -import mage.view.CardView; -import mage.view.CardsView; -import mage.view.ExileView; -import mage.view.GameView; -import mage.view.LookedAtView; -import mage.view.MatchView; -import mage.view.PlayerView; -import mage.view.RevealedView; -import mage.view.SimpleCardsView; -import mage.view.UserRequestMessage; +import mage.view.*; import org.apache.log4j.Logger; import org.mage.card.arcane.CardPanel; import org.mage.plugins.card.utils.impl.ImageManagerImpl; +import javax.swing.*; +import javax.swing.GroupLayout.Alignment; +import javax.swing.Timer; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; +import javax.swing.plaf.basic.BasicSplitPaneDivider; +import javax.swing.plaf.basic.BasicSplitPaneUI; +import java.awt.*; +import java.awt.event.*; +import java.io.Serializable; +import java.util.*; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import static mage.client.dialog.PreferencesDialog.*; +import static mage.constants.PlayerAction.*; + /** * @author BetaSteward_at_googlemail.com, nantuko8 */ @@ -2251,7 +2188,7 @@ public final class GamePanel extends javax.swing.JPanel { // Event listener for the ShowCardsDialog private Listener getShowCardsEventListener(final ShowCardsDialog dialog) { return (Listener) event -> { - if (event.getEventName().equals("show-popup-menu")) { + if (event.getEventType() == ClientEventType.SHOW_POP_UP_MENU) { if (event.getComponent() != null && event.getComponent() instanceof CardPanel) { JPopupMenu menu = ((CardPanel) event.getComponent()).getPopupMenu(); if (menu != null) { @@ -2260,7 +2197,7 @@ public final class GamePanel extends javax.swing.JPanel { } } } - if (event.getEventName().equals("action-consumed")) { + if (event.getEventType() == ClientEventType.ACTION_CONSUMED) { dialog.removeDialog(); } }; diff --git a/Mage.Client/src/main/java/mage/client/table/PlayerTypeEventSource.java b/Mage.Client/src/main/java/mage/client/table/PlayerTypeEventSource.java index f7d9d243dc..7c942fa508 100644 --- a/Mage.Client/src/main/java/mage/client/table/PlayerTypeEventSource.java +++ b/Mage.Client/src/main/java/mage/client/table/PlayerTypeEventSource.java @@ -28,11 +28,9 @@ package mage.client.table; +import mage.client.util.*; + import java.io.Serializable; -import mage.client.util.Event; -import mage.client.util.EventDispatcher; -import mage.client.util.EventSource; -import mage.client.util.Listener; /** * @@ -48,7 +46,7 @@ public class PlayerTypeEventSource implements EventSource, Serializable { } public void playerTypeChanged() { - dispatcher.fireEvent(new Event(null, "playerTypeChanged")); + dispatcher.fireEvent(new Event(null, ClientEventType.PLAYER_TYPE_CHANGED)); } @Override diff --git a/Mage.Client/src/main/java/mage/client/util/ClientEventType.java b/Mage.Client/src/main/java/mage/client/util/ClientEventType.java new file mode 100644 index 0000000000..252707f26c --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/ClientEventType.java @@ -0,0 +1,20 @@ +package mage.client.util; + +public enum ClientEventType { + SET_NUMBER, + ACTION_CONSUMED, + DOUBLE_CLICK, + ALT_DOUBLE_CLICK, + REMOVE_MAIN, + REMOVE_SIDEBOARD, + SHOW_POP_UP_MENU, + REMOVE_SPECIFIC_CARD, + ADD_SPECIFIC_CARD, + PICK_A_CARD, + MARK_A_CARD, + PLAYER_TYPE_CHANGED + + + + +} diff --git a/Mage.Client/src/main/java/mage/client/util/Event.java b/Mage.Client/src/main/java/mage/client/util/Event.java index bcf8b64ac8..f753ced26e 100644 --- a/Mage.Client/src/main/java/mage/client/util/Event.java +++ b/Mage.Client/src/main/java/mage/client/util/Event.java @@ -38,27 +38,27 @@ import java.io.Serializable; public class Event implements Serializable { private final Object source; private final Component component; - private final String eventName; + private final ClientEventType eventType; private final int number; private final int xPos; private final int yPos; - public Event(Object source, String eventName) { - this(source, eventName, 0); + public Event(Object source, ClientEventType eventType) { + this(source, eventType, 0); } - public Event(Object source, String eventName, int number) { + public Event(Object source, ClientEventType eventType, int number) { this.source = source; - this.eventName = eventName; + this.eventType = eventType; this.number = number; this.xPos = 0; this.yPos = 0; this.component = null; } - public Event(Object source, String eventName, int xPos, int yPos, Component component) { + public Event(Object source, ClientEventType eventType, int xPos, int yPos, Component component) { this.source = source; - this.eventName = eventName; + this.eventType = eventType; this.number =0; this.xPos = xPos; this.yPos = yPos; @@ -69,8 +69,8 @@ public class Event implements Serializable { return source; } - public String getEventName() { - return eventName; + public ClientEventType getEventType() { + return eventType; } public int getNumber() { From bda8736b9ed4e9b787cdd16f4daff8a8e4b5233e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 3 Oct 2017 17:06:46 +0200 Subject: [PATCH 22/68] Some minot fixes /changes. --- Mage.Server/src/main/java/mage/server/MageServerImpl.java | 2 -- Mage.Sets/src/mage/cards/s/SliceInTwain.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 463a5b9d7e..f25de76395 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -548,8 +548,6 @@ public class MageServerImpl implements MageServer { UUID userId = session.get().getUserId(); ChatManager.instance.leaveChat(chatId, userId); } - } else { - logger.warn("The chatId is null. sessionId = " + sessionId); } }); } diff --git a/Mage.Sets/src/mage/cards/s/SliceInTwain.java b/Mage.Sets/src/mage/cards/s/SliceInTwain.java index 4e1695832a..1c01b61ab2 100644 --- a/Mage.Sets/src/mage/cards/s/SliceInTwain.java +++ b/Mage.Sets/src/mage/cards/s/SliceInTwain.java @@ -46,7 +46,7 @@ public class SliceInTwain extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("
br>Draw a card")); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); } From 4a71f8af67e4f0cab104108e2a5a53e5524d1f21 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 3 Oct 2017 17:24:35 +0200 Subject: [PATCH 23/68] Some minot fixes /changes. --- Mage.Sets/src/mage/cards/t/TheScarabGod.java | 1 - Mage/src/main/java/mage/MageObjectImpl.java | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/t/TheScarabGod.java b/Mage.Sets/src/mage/cards/t/TheScarabGod.java index d9873f8690..94b771e9fa 100644 --- a/Mage.Sets/src/mage/cards/t/TheScarabGod.java +++ b/Mage.Sets/src/mage/cards/t/TheScarabGod.java @@ -40,7 +40,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenCopyTargetEffect; -import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java index 879bb06b58..e733dc1fba 100644 --- a/Mage/src/main/java/mage/MageObjectImpl.java +++ b/Mage/src/main/java/mage/MageObjectImpl.java @@ -342,6 +342,9 @@ public abstract class MageObjectImpl implements MageObject { } } + /** + * Remove power/toughness character defining abilities + */ @Override public void removePTCDA() { for (Iterator iter = this.getAbilities().iterator(); iter.hasNext();) { From d69e0f37d30cb958aa885a954ec83d71569c4f0d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 3 Oct 2017 11:36:16 -0400 Subject: [PATCH 24/68] Implemented Riptide Mangler --- .../src/mage/cards/r/RiptideMangler.java | 103 ++++++++++++++++++ Mage.Sets/src/mage/sets/Legions.java | 1 + 2 files changed, 104 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RiptideMangler.java diff --git a/Mage.Sets/src/mage/cards/r/RiptideMangler.java b/Mage.Sets/src/mage/cards/r/RiptideMangler.java new file mode 100644 index 0000000000..13b4d08069 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RiptideMangler.java @@ -0,0 +1,103 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class RiptideMangler extends CardImpl { + + public RiptideMangler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // {1}{U}: Change Riptide Mangler's base power to target creature's power. + Ability ability = new SimpleActivatedAbility(new RiptideManglerEffect(), new ManaCostsImpl("{1}{U}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public RiptideMangler(final RiptideMangler card) { + super(card); + } + + @Override + public RiptideMangler copy() { + return new RiptideMangler(this); + } +} + +class RiptideManglerEffect extends OneShotEffect { + + RiptideManglerEffect() { + super(Outcome.BoostCreature); + this.staticText = "Change {this}'s base power to target creature's power. (This effect lasts indefinitely.)"; + } + + RiptideManglerEffect(final RiptideManglerEffect effect) { + super(effect); + } + + @Override + public RiptideManglerEffect copy() { + return new RiptideManglerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + game.addEffect(new SetPowerSourceEffect(new StaticValue(permanent.getPower().getValue()), Duration.WhileOnBattlefield, SubLayer.SetPT_7b), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index 823c670491..8d8368aca7 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -152,6 +152,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Quick Sliver", 136, Rarity.COMMON, mage.cards.q.QuickSliver.class)); cards.add(new SetCardInfo("Ridgetop Raptor", 108, Rarity.UNCOMMON, mage.cards.r.RidgetopRaptor.class)); cards.add(new SetCardInfo("Riptide Director", 50, Rarity.RARE, mage.cards.r.RiptideDirector.class)); + cards.add(new SetCardInfo("Riptide Mangler", 51, Rarity.RARE, mage.cards.r.RiptideMangler.class)); cards.add(new SetCardInfo("Rockshard Elemental", 109, Rarity.RARE, mage.cards.r.RockshardElemental.class)); cards.add(new SetCardInfo("Root Sliver", 137, Rarity.UNCOMMON, mage.cards.r.RootSliver.class)); cards.add(new SetCardInfo("Scion of Darkness", 79, Rarity.RARE, mage.cards.s.ScionOfDarkness.class)); From 71336a916d465b2e5723d1a5d1c28dcb941bbe45 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 3 Oct 2017 18:41:06 +0200 Subject: [PATCH 25/68] XMage 1.4.26V7 --- .../src/main/java/mage/utils/MageVersion.java | 2 +- .../src/mage/cards/f/FracturedLoyalty.java | 30 +++++++++---------- .../mage/cards/repository/CardRepository.java | 2 +- Utils/find_new_cards.pl | 27 ++++++++++++++++- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 1c572fe2b6..00d203ef6c 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 26; - public final static String MAGE_VERSION_MINOR_PATCH = "V6"; + public final static String MAGE_VERSION_MINOR_PATCH = "V7"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java index db4928c64a..2ce91ccbe8 100644 --- a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java +++ b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java @@ -28,7 +28,6 @@ package mage.cards.f; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.ContinuousEffect; @@ -48,8 +47,6 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.common.SimpleStaticAbility; /** * @@ -58,7 +55,7 @@ import mage.abilities.common.SimpleStaticAbility; public class FracturedLoyalty extends CardImpl { public FracturedLoyalty(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -85,7 +82,7 @@ public class FracturedLoyalty extends CardImpl { public FracturedLoyaltyEffect() { super(Outcome.GainControl); - this.staticText = "that player gains control of that creature"; + this.staticText = "that spell or ability's controller gains control of that creature"; } private FracturedLoyaltyEffect(FracturedLoyaltyEffect effect) { @@ -95,21 +92,23 @@ public class FracturedLoyalty extends CardImpl { @Override public boolean apply(Game game, Ability source) { Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); - Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); - Player controller = game.getPlayer(enchantedCreature.getControllerId()); - Player newController = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if (enchantment != null && enchantment.getAttachedTo() != null) { - if (newController != null && controller != null && !controller.equals(newController)) { - ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newController.getId()); - effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); - game.addEffect(effect, source); - return true; + if (enchantment != null) { + Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo()); + if (enchantedCreature != null) { + Player controller = game.getPlayer(enchantedCreature.getControllerId()); + if (enchantment.getAttachedTo() != null) { + if (controller != null && !enchantedCreature.getControllerId().equals(this.getTargetPointer().getFirst(game, source))) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, this.getTargetPointer().getFirst(game, source)); + effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); + game.addEffect(effect, source); + return true; + } + } } } return false; } - @Override public Effect copy() { return new FracturedLoyaltyEffect(this); @@ -150,7 +149,6 @@ public class FracturedLoyalty extends CardImpl { return false; } - @Override public String getRule() { return "Whenever enchanted creature becomes the target of a spell or ability, that spell or ability's controller gains control of that creature."; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index c8c3245cfe..91530a64df 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 93; + private static final long CARD_CONTENT_VERSION = 94; private Dao cardDao; private Set classNames; diff --git a/Utils/find_new_cards.pl b/Utils/find_new_cards.pl index 6970d3d92e..db6a7db5f3 100644 --- a/Utils/find_new_cards.pl +++ b/Utils/find_new_cards.pl @@ -81,6 +81,7 @@ sub get_name_of_card_from_class $card_name =~ s/ Of / of /g; $card_name =~ s/ To / to /g; $card_name =~ s/ And / and /g; + $card_name =~ s/ For / for /g; return $card_name; } return ""; @@ -143,7 +144,31 @@ if (exists ($new_order{$cmd})) { if ($new_cards {$line} > 0) { - print ($line, " in ", $all_cards {$line}, "\n"); + my $setname = $all_cards {$line}; + + # Check if name is correct if not try to fix with ' before the endings of first word + no warnings 'uninitialized'; + if (!(length $setname)) { # setname is not set correct + my $firstblank = index($line, " "); + my $char = substr $line, $firstblank - 1, 1; + if ($char eq "s") { + my $fixedname = (substr $line, 0, $firstblank - 1) . "'" . (substr $line , $firstblank -1); + $setname = $all_cards {$fixedname}; + if (length $setname) { + $line = $fixedname; + } + } + } + + + if (!(length $setname)){ + print ("*** Set not found - probably card name is not exactly correct\n"); + print ($line, "\n"); + } else { + print ($line, " in ", $setname, "\n"); + } + + } } } From 1453fa46a78d3852c64623f2ef5491b49ef48ecb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 3 Oct 2017 15:52:58 -0400 Subject: [PATCH 26/68] Fixed Urborg's functionality, also fixed Scarwood Hag not removing forestwalk properly (#4088) --- Mage.Sets/src/mage/cards/u/Urborg.java | 48 +++++++++++++++++-- .../continuous/LoseAbilityTargetEffect.java | 15 +++++- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/u/Urborg.java b/Mage.Sets/src/mage/cards/u/Urborg.java index 967c4d39bd..a8f163a894 100644 --- a/Mage.Sets/src/mage/cards/u/Urborg.java +++ b/Mage.Sets/src/mage/cards/u/Urborg.java @@ -31,15 +31,22 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.continuous.LoseAbilityOrAnotherAbilityTargetEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.SwampwalkAbility; import mage.abilities.mana.BlackManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetCreaturePermanent; /** @@ -49,13 +56,14 @@ import mage.target.common.TargetCreaturePermanent; public class Urborg extends CardImpl { public Urborg(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); addSuperType(SuperType.LEGENDARY); // {tap}: Add {B} to your mana pool. this.addAbility(new BlackManaAbility()); + // {tap}: Target creature loses first strike or swampwalk until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAbilityOrAnotherAbilityTargetEffect(FirstStrikeAbility.getInstance(), new SwampwalkAbility()), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UrborgEffect(), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } @@ -70,4 +78,38 @@ public class Urborg extends CardImpl { } } +class UrborgEffect extends OneShotEffect { + UrborgEffect() { + super(Outcome.Benefit); + this.staticText = "Target creature loses first strike or swampwalk until end of turn."; + } + + UrborgEffect(final UrborgEffect effect) { + super(effect); + } + + @Override + public UrborgEffect copy() { + return new UrborgEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (player == null || permanent == null) { + return false; + } + Ability ability; + if (player.chooseUse(Outcome.UnboostCreature, "Which ability should be lost?", null, "First Strike", "Swampwalk", source, game)) { + ability = FirstStrikeAbility.getInstance(); + } else { + ability = new SwampwalkAbility(); + } + ContinuousEffect effect = new LoseAbilityTargetEffect(ability, Duration.EndOfTurn); +// effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java index 3ac29f8314..a27e56fa95 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java @@ -27,7 +27,9 @@ */ package mage.abilities.effects.common.continuous; +import java.util.Iterator; import mage.abilities.Ability; +import mage.abilities.MageSingleton; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -69,8 +71,17 @@ public class LoseAbilityTargetEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { - while (permanent.getAbilities().contains(ability)) { - permanent.getAbilities().remove(ability); + if (ability instanceof MageSingleton) { + while (permanent.getAbilities().contains(ability)) { + permanent.getAbilities().remove(ability); + } + } else { + for (Iterator iter = permanent.getAbilities().iterator(); iter.hasNext();) { + Ability ab = iter.next(); + if (ab.getClass().equals(ability.getClass())) { + iter.remove(); + } + } } } return true; From 83338520259b429a328614c50dd53bef044438b1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 3 Oct 2017 16:04:29 -0400 Subject: [PATCH 27/68] Implemented Hammerheim --- Mage.Sets/src/mage/cards/h/Hammerheim.java | 115 ++++++++++++++++++ Mage.Sets/src/mage/sets/Legends.java | 1 + .../src/mage/sets/MastersEditionIII.java | 1 + 3 files changed, 117 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/Hammerheim.java diff --git a/Mage.Sets/src/mage/cards/h/Hammerheim.java b/Mage.Sets/src/mage/cards/h/Hammerheim.java new file mode 100644 index 0000000000..0ce0f09fdb --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/Hammerheim.java @@ -0,0 +1,115 @@ +/* + * 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.h; + +import java.util.Iterator; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.keyword.LandwalkAbility; +import mage.abilities.mana.RedManaAbility; +import mage.constants.SuperType; +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.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class Hammerheim extends CardImpl { + + public Hammerheim(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + + // {tap}: Add {R} to your mana pool. + this.addAbility(new RedManaAbility()); + + // {tap}: Target creature loses all landwalk abilities until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HammerheimEffect(), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public Hammerheim(final Hammerheim card) { + super(card); + } + + @Override + public Hammerheim copy() { + return new Hammerheim(this); + } +} + +class HammerheimEffect extends ContinuousEffectImpl { + + public HammerheimEffect() { + super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility); + } + + public HammerheimEffect(final HammerheimEffect effect) { + super(effect); + } + + @Override + public HammerheimEffect copy() { + return new HammerheimEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + for (Iterator iter = permanent.getAbilities().iterator(); iter.hasNext();) { + Ability ab = iter.next(); + if (ab instanceof LandwalkAbility) { + iter.remove(); + } + } + } + return true; + } + + @Override + public String getText(Mode mode) { + return "Target creature loses all landwalk abilities until end of turn."; + } +} diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 393cbee13f..8ffb47146f 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -130,6 +130,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Greed", 15, Rarity.RARE, mage.cards.g.Greed.class)); cards.add(new SetCardInfo("Green Mana Battery", 223, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class)); cards.add(new SetCardInfo("Gwendlyn Di Corci", 268, Rarity.RARE, mage.cards.g.GwendlynDiCorci.class)); + cards.add(new SetCardInfo("Hammerheim", 247, Rarity.UNCOMMON, mage.cards.h.Hammerheim.class)); cards.add(new SetCardInfo("Hazezon Tamar", 270, Rarity.RARE, mage.cards.h.HazezonTamar.class)); cards.add(new SetCardInfo("Headless Horseman", 16, Rarity.COMMON, mage.cards.h.HeadlessHorseman.class)); cards.add(new SetCardInfo("Heaven's Gate", 188, Rarity.UNCOMMON, mage.cards.h.HeavensGate.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index 596bb603a2..5d732eceba 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -128,6 +128,7 @@ public class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Guan Yu's 1,000-Li March", 13, Rarity.RARE, mage.cards.g.GuanYus1000LiMarch.class)); cards.add(new SetCardInfo("Guan Yu, Sainted Warrior", 12, Rarity.UNCOMMON, mage.cards.g.GuanYuSaintedWarrior.class)); cards.add(new SetCardInfo("Gwendlyn Di Corci", 149, Rarity.RARE, mage.cards.g.GwendlynDiCorci.class)); + cards.add(new SetCardInfo("Hammerheim", 207, Rarity.UNCOMMON, mage.cards.h.Hammerheim.class)); cards.add(new SetCardInfo("Hazezon Tamar", 151, Rarity.RARE, mage.cards.h.HazezonTamar.class)); cards.add(new SetCardInfo("Heal", 14, Rarity.COMMON, mage.cards.h.Heal.class)); cards.add(new SetCardInfo("Hellfire", 70, Rarity.RARE, mage.cards.h.Hellfire.class)); From 0ebe09d468b6afbb727ee98e4c08f21bb3371e50 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 12:13:22 -0400 Subject: [PATCH 28/68] Reenabled Mage Verify, reverted Ripscale Predator to lizard (for now) --- Mage.Sets/src/mage/cards/r/RipscalePredator.java | 2 +- Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/r/RipscalePredator.java b/Mage.Sets/src/mage/cards/r/RipscalePredator.java index 916b3383d9..1ec9116f57 100644 --- a/Mage.Sets/src/mage/cards/r/RipscalePredator.java +++ b/Mage.Sets/src/mage/cards/r/RipscalePredator.java @@ -43,7 +43,7 @@ public class RipscalePredator extends CardImpl { public RipscalePredator(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); - this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.LIZARD); this.power = new MageInt(6); this.toughness = new MageInt(5); diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index bf06ef019e..a0b1a11314 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -16,7 +16,6 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.junit.Ignore; public class VerifyCardDataTest { @@ -49,7 +48,6 @@ public class VerifyCardDataTest { private int failed = 0; - @Ignore @Test public void verifyCards() throws IOException { for (Card card : allCards()) { From 6725c50b4ad716e8d800157ef50b28e2829aeda6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 14:19:10 -0400 Subject: [PATCH 29/68] Implemented Elder Land Wurm --- Mage.Sets/src/mage/cards/e/ElderLandWurm.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/FourthEdition.java | 1 + Mage.Sets/src/mage/sets/Legends.java | 1 + Mage.Sets/src/mage/sets/MastersEdition.java | 1 + .../common/BlocksTriggeredAbility.java | 9 ++- 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/e/ElderLandWurm.java diff --git a/Mage.Sets/src/mage/cards/e/ElderLandWurm.java b/Mage.Sets/src/mage/cards/e/ElderLandWurm.java new file mode 100644 index 0000000000..7ce9c4ade3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElderLandWurm.java @@ -0,0 +1,74 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author TheElk801 + */ +public class ElderLandWurm extends CardImpl { + + public ElderLandWurm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}{W}"); + + this.subtype.add(SubType.DRAGON); + this.subtype.add(SubType.WURM); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When Elder Land Wurm blocks, it loses defender. + this.addAbility(new BlocksTriggeredAbility(new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.Custom), false, false, true)); + } + + public ElderLandWurm(final ElderLandWurm card) { + super(card); + } + + @Override + public ElderLandWurm copy() { + return new ElderLandWurm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FourthEdition.java b/Mage.Sets/src/mage/sets/FourthEdition.java index e16e0f3d26..c1a6349a31 100644 --- a/Mage.Sets/src/mage/sets/FourthEdition.java +++ b/Mage.Sets/src/mage/sets/FourthEdition.java @@ -151,6 +151,7 @@ public class FourthEdition extends ExpansionSet { cards.add(new SetCardInfo("Earthquake", 207, Rarity.RARE, mage.cards.e.Earthquake.class)); cards.add(new SetCardInfo("Ebony Horse", 336, Rarity.RARE, mage.cards.e.EbonyHorse.class)); cards.add(new SetCardInfo("El-Hajjaj", 18, Rarity.RARE, mage.cards.e.ElHajjaj.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 274, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); cards.add(new SetCardInfo("Elven Riders", 126, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class)); cards.add(new SetCardInfo("Elvish Archers", 127, Rarity.RARE, mage.cards.e.ElvishArchers.class)); cards.add(new SetCardInfo("Energy Flux", 68, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class)); diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 8ffb47146f..e0a7f3f724 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -106,6 +106,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("Divine Transformation", 179, Rarity.RARE, mage.cards.d.DivineTransformation.class)); cards.add(new SetCardInfo("Durkwood Boars", 96, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); cards.add(new SetCardInfo("Dwarven Song", 141, Rarity.UNCOMMON, mage.cards.d.DwarvenSong.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 180, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); cards.add(new SetCardInfo("Elven Riders", 97, Rarity.RARE, mage.cards.e.ElvenRiders.class)); cards.add(new SetCardInfo("Emerald Dragonfly", 98, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); cards.add(new SetCardInfo("Energy Tap", 54, Rarity.COMMON, mage.cards.e.EnergyTap.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEdition.java b/Mage.Sets/src/mage/sets/MastersEdition.java index 686f03adbc..9ca7deb821 100644 --- a/Mage.Sets/src/mage/sets/MastersEdition.java +++ b/Mage.Sets/src/mage/sets/MastersEdition.java @@ -108,6 +108,7 @@ public class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Dwarven Catapult", 91, Rarity.UNCOMMON, mage.cards.d.DwarvenCatapult.class)); cards.add(new SetCardInfo("Dwarven Soldier", 92, Rarity.COMMON, DwarvenSoldier.class)); cards.add(new SetCardInfo("Eater of the Dead", 67, Rarity.UNCOMMON, mage.cards.e.EaterOfTheDead.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class)); cards.add(new SetCardInfo("Erg Raiders", 68, Rarity.COMMON, mage.cards.e.ErgRaiders.class)); cards.add(new SetCardInfo("Eureka", 117, Rarity.RARE, mage.cards.e.Eureka.class)); cards.add(new SetCardInfo("Exile", 12, Rarity.COMMON, mage.cards.e.Exile.class)); diff --git a/Mage/src/main/java/mage/abilities/common/BlocksTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BlocksTriggeredAbility.java index d82fe4c8ba..bb5da984e8 100644 --- a/Mage/src/main/java/mage/abilities/common/BlocksTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BlocksTriggeredAbility.java @@ -41,19 +41,26 @@ import mage.target.targetpointer.FixedTarget; public class BlocksTriggeredAbility extends TriggeredAbilityImpl { private boolean setTargetPointer; + private boolean once = false; public BlocksTriggeredAbility(Effect effect, boolean optional) { this(effect, optional, false); } public BlocksTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { + this(effect, optional, setTargetPointer, false); + } + + public BlocksTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer, boolean once) { super(Zone.BATTLEFIELD, effect, optional); this.setTargetPointer = setTargetPointer; + this.once = once; } public BlocksTriggeredAbility(final BlocksTriggeredAbility ability) { super(ability); this.setTargetPointer = ability.setTargetPointer; + this.once = ability.once; } @Override @@ -76,7 +83,7 @@ public class BlocksTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever {this} blocks" + (setTargetPointer ? " a creature, " : ", ") + super.getRule(); + return "When" + (once ? "" : "ever") + " {this} blocks" + (setTargetPointer ? " a creature, " : ", ") + super.getRule(); } @Override From ee5bd655c6843d490dba589737374a1840d8997d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 14:32:13 -0400 Subject: [PATCH 30/68] Implemented Alaborn Zealot, fixed text on several cards with block triggers --- .../src/mage/cards/a/AgelessSentinels.java | 2 +- Mage.Sets/src/mage/cards/a/AlabornZealot.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/cards/c/CinderWall.java | 9 +-- .../src/mage/cards/d/DefiantVanguard.java | 5 +- Mage.Sets/src/mage/cards/l/LoyalSentry.java | 41 ++--------- Mage.Sets/src/mage/cards/s/StoicEphemera.java | 9 ++- Mage.Sets/src/mage/cards/w/WallOfJunk.java | 4 +- Mage.Sets/src/mage/cards/z/ZephyrSpirit.java | 4 +- Mage.Sets/src/mage/sets/PortalSecondAge.java | 1 + 9 files changed, 96 insertions(+), 48 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AlabornZealot.java diff --git a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java index bd3f73d3d6..fe9bd4e47b 100644 --- a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java +++ b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java @@ -67,7 +67,7 @@ public class AgelessSentinels extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Ageless Sentinels blocks, it becomes a Bird Giant, and it loses defender. - Ability ability = new BlocksTriggeredAbility(new AgelessSentinelsEffect(), false); + Ability ability = new BlocksTriggeredAbility(new AgelessSentinelsEffect(), false, false, true); Effect effect = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.WhileOnBattlefield); effect.setText("and it loses defender"); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/a/AlabornZealot.java b/Mage.Sets/src/mage/cards/a/AlabornZealot.java new file mode 100644 index 0000000000..37b137ba16 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AlabornZealot.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.effects.common.DestroySourceEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class AlabornZealot extends CardImpl { + + public AlabornZealot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Alaborn Zealot blocks a creature, destroy that creature and Alaborn Zealot. + Ability ability = new BlocksTriggeredAbility(new DestroyTargetEffect().setText("destroy that creature"), false, true, true); + ability.addEffect(new DestroySourceEffect().setText("and {this}")); + this.addAbility(ability); + } + + public AlabornZealot(final AlabornZealot card) { + super(card); + } + + @Override + public AlabornZealot copy() { + return new AlabornZealot(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CinderWall.java b/Mage.Sets/src/mage/cards/c/CinderWall.java index 94215962aa..3d7b059518 100644 --- a/Mage.Sets/src/mage/cards/c/CinderWall.java +++ b/Mage.Sets/src/mage/cards/c/CinderWall.java @@ -46,7 +46,7 @@ import mage.constants.SubType; public class CinderWall extends CardImpl { public CinderWall(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.WALL); this.power = new MageInt(3); @@ -55,9 +55,10 @@ public class CinderWall extends CardImpl { // Defender this.addAbility(DefenderAbility.getInstance()); // When Cinder Wall blocks, destroy it at end of combat. - this.addAbility( - new BlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DestroySourceEffect())) - , false)); + this.addAbility(new BlocksTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DestroySourceEffect())), + false, false, true + )); } public CinderWall(final CinderWall card) { diff --git a/Mage.Sets/src/mage/cards/d/DefiantVanguard.java b/Mage.Sets/src/mage/cards/d/DefiantVanguard.java index 45de395c37..3b28b8d6dc 100644 --- a/Mage.Sets/src/mage/cards/d/DefiantVanguard.java +++ b/Mage.Sets/src/mage/cards/d/DefiantVanguard.java @@ -80,7 +80,10 @@ public class DefiantVanguard extends CardImpl { // When Defiant Vanguard blocks, at end of combat, destroy it and all creatures it blocked this turn. this.addAbility( - new BlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DefiantVanguardEffect())), false), + new BlocksTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DefiantVanguardEffect())), + false, false, true + ), new BlockedAttackerWatcher() ); diff --git a/Mage.Sets/src/mage/cards/l/LoyalSentry.java b/Mage.Sets/src/mage/cards/l/LoyalSentry.java index 0f58f0d88a..d7ba486a57 100644 --- a/Mage.Sets/src/mage/cards/l/LoyalSentry.java +++ b/Mage.Sets/src/mage/cards/l/LoyalSentry.java @@ -31,14 +31,12 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BlocksTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroySourceEffect; +import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.permanent.Permanent; /** * @@ -55,7 +53,9 @@ public class LoyalSentry extends CardImpl { this.toughness = new MageInt(1); // When Loyal Sentry blocks a creature, destroy that creature and Loyal Sentry. - this.addAbility(new BlocksTriggeredAbility(new LoyalSentryEffect(), false, true)); + Ability ability = new BlocksTriggeredAbility(new DestroyTargetEffect().setText("destroy that creature"), false, true, true); + ability.addEffect(new DestroySourceEffect().setText("and {this}")); + this.addAbility(ability); } public LoyalSentry(final LoyalSentry card) { @@ -67,34 +67,3 @@ public class LoyalSentry extends CardImpl { return new LoyalSentry(this); } } - -class LoyalSentryEffect extends OneShotEffect { - - LoyalSentryEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature and {this}"; - } - - LoyalSentryEffect(LoyalSentryEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (p != null) { - p.destroy(source.getSourceId(), game, false); - } - Permanent s = game.getPermanent(source.getSourceId()); - if (s != null) { - s.destroy(source.getSourceId(), game, false); - } - return true; - } - - @Override - public LoyalSentryEffect copy() { - return new LoyalSentryEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/s/StoicEphemera.java b/Mage.Sets/src/mage/cards/s/StoicEphemera.java index 2c78feb9be..9587de28d8 100644 --- a/Mage.Sets/src/mage/cards/s/StoicEphemera.java +++ b/Mage.Sets/src/mage/cards/s/StoicEphemera.java @@ -47,7 +47,7 @@ import mage.constants.SubType; public class StoicEphemera extends CardImpl { public StoicEphemera(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(5); this.toughness = new MageInt(5); @@ -57,8 +57,11 @@ public class StoicEphemera extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // When Stoic Ephemera blocks, sacrifice it at end of combat. - this.addAbility(new BlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( - new AtTheEndOfCombatDelayedTriggeredAbility(new SacrificeSourceEffect())), false)); + this.addAbility(new BlocksTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new SacrificeSourceEffect()) + ), false, false, true + )); } public StoicEphemera(final StoicEphemera card) { diff --git a/Mage.Sets/src/mage/cards/w/WallOfJunk.java b/Mage.Sets/src/mage/cards/w/WallOfJunk.java index 7aab73c462..39bf45f978 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfJunk.java +++ b/Mage.Sets/src/mage/cards/w/WallOfJunk.java @@ -47,7 +47,7 @@ import mage.constants.SubType; public class WallOfJunk extends CardImpl { public WallOfJunk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); this.subtype.add(SubType.WALL); this.power = new MageInt(0); this.toughness = new MageInt(7); @@ -59,7 +59,7 @@ public class WallOfJunk extends CardImpl { Effect effect = new CreateDelayedTriggeredAbilityEffect( new AtTheEndOfCombatDelayedTriggeredAbility(new ReturnToHandSourceEffect(true))); effect.setText("return it to its owner's hand at end of combat"); - this.addAbility(new BlocksTriggeredAbility(effect, false)); + this.addAbility(new BlocksTriggeredAbility(effect, false, false, true)); } public WallOfJunk(final WallOfJunk card) { diff --git a/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java b/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java index 1696fcde21..dc852ff723 100644 --- a/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java +++ b/Mage.Sets/src/mage/cards/z/ZephyrSpirit.java @@ -51,7 +51,9 @@ public class ZephyrSpirit extends CardImpl { // 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)); + new ReturnToHandSourceEffect(true).setText("return it to its owner's hand"), + false, false, true + )); } public ZephyrSpirit(final ZephyrSpirit card) { diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index 8c36225d91..1abbd4e4ed 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -64,6 +64,7 @@ public class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Alaborn Musketeer", 123, Rarity.COMMON, mage.cards.a.AlabornMusketeer.class)); cards.add(new SetCardInfo("Alaborn Trooper", 124, Rarity.COMMON, mage.cards.a.AlabornTrooper.class)); cards.add(new SetCardInfo("Alaborn Veteran", 125, Rarity.RARE, mage.cards.a.AlabornVeteran.class)); + cards.add(new SetCardInfo("Alaborn Zealot", 126, Rarity.UNCOMMON, mage.cards.a.AlabornZealot.class)); cards.add(new SetCardInfo("Alluring Scent", 61, Rarity.RARE, mage.cards.a.AlluringScent.class)); cards.add(new SetCardInfo("Ancient Craving", 2, Rarity.RARE, mage.cards.a.AncientCraving.class)); cards.add(new SetCardInfo("Angelic Blessing", 129, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); From 54093ec0f26084378fe7ca0fb4915345bcf8c2a2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 14:45:51 -0400 Subject: [PATCH 31/68] Implemented Return of the Nightstalkers --- .../cards/r/ReturnOfTheNightstalkers.java | 107 ++++++++++++++++++ Mage.Sets/src/mage/sets/PortalSecondAge.java | 1 + 2 files changed, 108 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java diff --git a/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java b/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java new file mode 100644 index 0000000000..e4fc525b19 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +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.common.FilterControlledPermanent; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class ReturnOfTheNightstalkers extends CardImpl { + + public ReturnOfTheNightstalkers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}"); + + // Return all Nightstalker permanent cards from your graveyard to the battlefield. Then destroy all Swamps you control. + this.getSpellAbility().addEffect(new ReturnOfTheNightstalkersEffect()); + } + + public ReturnOfTheNightstalkers(final ReturnOfTheNightstalkers card) { + super(card); + } + + @Override + public ReturnOfTheNightstalkers copy() { + return new ReturnOfTheNightstalkers(this); + } +} + +class ReturnOfTheNightstalkersEffect extends OneShotEffect { + + private static final FilterPermanentCard filter1 = new FilterPermanentCard(); + private static final FilterControlledPermanent filter2 = new FilterControlledPermanent(); + + static { + filter1.add(new SubtypePredicate(SubType.NIGHTSTALKER)); + filter2.add(new SubtypePredicate(SubType.SWAMP)); + } + + public ReturnOfTheNightstalkersEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "Return all Nightstalker permanent cards from your graveyard to the battlefield. Then destroy all Swamps you control."; + } + + public ReturnOfTheNightstalkersEffect(final ReturnOfTheNightstalkersEffect effect) { + super(effect); + } + + @Override + public ReturnOfTheNightstalkersEffect copy() { + return new ReturnOfTheNightstalkersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + for (Card card : player.getGraveyard().getCards(filter1, game)) { + card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); + } + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter2, source.getControllerId(), source.getSourceId(), game)) { + permanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index 1abbd4e4ed..1f583f0101 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -167,6 +167,7 @@ public class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Raise Dead", 26, Rarity.COMMON, mage.cards.r.RaiseDead.class)); cards.add(new SetCardInfo("Ravenous Rats", 27, Rarity.COMMON, mage.cards.r.RavenousRats.class)); cards.add(new SetCardInfo("Razorclaw Bear", 82, Rarity.RARE, mage.cards.r.RazorclawBear.class)); + cards.add(new SetCardInfo("Return of the Nightstalkers", 28, Rarity.RARE, mage.cards.r.ReturnOfTheNightstalkers.class)); cards.add(new SetCardInfo("Righteous Charge", 140, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); cards.add(new SetCardInfo("Righteous Fury", 141, Rarity.RARE, mage.cards.r.RighteousFury.class)); cards.add(new SetCardInfo("River Bear", 84, Rarity.UNCOMMON, mage.cards.r.RiverBear.class)); From 36fab02278eb3e85d2e9330518dc4ca9986e8516 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 16:05:20 -0400 Subject: [PATCH 32/68] Implemented Orcish Squatters --- Mage.Sets/src/mage/cards/m/MasterThief.java | 22 ++--- .../src/mage/cards/o/OrcishSquatters.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/FifthEdition.java | 1 + Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 5 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/o/OrcishSquatters.java diff --git a/Mage.Sets/src/mage/cards/m/MasterThief.java b/Mage.Sets/src/mage/cards/m/MasterThief.java index 1e530ab13c..c989f62dfe 100644 --- a/Mage.Sets/src/mage/cards/m/MasterThief.java +++ b/Mage.Sets/src/mage/cards/m/MasterThief.java @@ -25,13 +25,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.m; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility; import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; @@ -40,22 +39,15 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; /** * @author Loki */ public class MasterThief extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifact"); - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - public MasterThief(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); @@ -63,12 +55,12 @@ public class MasterThief extends CardImpl { this.toughness = new MageInt(2); // When Master Thief enters the battlefield, gain control of target artifact for as long as you control Master Thief. - ConditionalContinuousEffect effect = new ConditionalContinuousEffect( + Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new ConditionalContinuousEffect( new GainControlTargetEffect(Duration.Custom), new SourceOnBattlefieldControlUnchangedCondition(), - "gain control of target artifact for as long as you control Master Thief"); - Ability ability = new EntersBattlefieldTriggeredAbility(effect, false); - ability.addTarget(new TargetPermanent(filter)); + "gain control of target artifact for as long as you control {this}" + ), false); + ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OrcishSquatters.java b/Mage.Sets/src/mage/cards/o/OrcishSquatters.java new file mode 100644 index 0000000000..ef0d26dd3e --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OrcishSquatters.java @@ -0,0 +1,85 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility; +import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class OrcishSquatters extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("land defending player controls"); + + static { + filter.add(new DefendingPlayerControlsPredicate()); + } + + public OrcishSquatters(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.ORC); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever Orcish Squatters attacks and isn't blocked, you may gain control of target land defending player controls for as long as you control Orcish Squatters. If you do, Orcish Squatters assigns no combat damage this turn. + Ability ability = new AttacksAndIsNotBlockedTriggeredAbility(new ConditionalContinuousEffect( + new GainControlTargetEffect(Duration.Custom), + new SourceOnBattlefieldControlUnchangedCondition(), + "gain control of target land defending player controls for as long as you control {this}" + ), true); + ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true)); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public OrcishSquatters(final OrcishSquatters card) { + super(card); + } + + @Override + public OrcishSquatters copy() { + return new OrcishSquatters(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index 7fea1ce413..d2247f8bf0 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -299,6 +299,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Orcish Artillery", 253, Rarity.UNCOMMON, mage.cards.o.OrcishArtillery.class)); cards.add(new SetCardInfo("Orcish Captain", 254, Rarity.UNCOMMON, mage.cards.o.OrcishCaptain.class)); cards.add(new SetCardInfo("Orcish Oriflamme", 257, Rarity.UNCOMMON, mage.cards.o.OrcishOriflamme.class)); + cards.add(new SetCardInfo("Orcish Squatters", 258, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 324, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 325, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); cards.add(new SetCardInfo("Orgg", 259, Rarity.RARE, mage.cards.o.Orgg.class)); diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 6468270c6f..2fea7b8b4c 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -229,6 +229,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Orcish Healer", 208, Rarity.UNCOMMON, mage.cards.o.OrcishHealer.class)); cards.add(new SetCardInfo("Orcish Librarian", 209, Rarity.RARE, mage.cards.o.OrcishLibrarian.class)); cards.add(new SetCardInfo("Orcish Lumberjack", 210, Rarity.COMMON, mage.cards.o.OrcishLumberjack.class)); + cards.add(new SetCardInfo("Orcish Squatters", 211, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 269, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 270, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); cards.add(new SetCardInfo("Pale Bears", 144, Rarity.RARE, mage.cards.p.PaleBears.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index bd326a4dd4..a762138985 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -183,6 +183,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Orcish Cannoneers", 138, Rarity.UNCOMMON, mage.cards.o.OrcishCannoneers.class)); cards.add(new SetCardInfo("Orcish Captain", 139, Rarity.UNCOMMON, mage.cards.o.OrcishCaptain.class)); cards.add(new SetCardInfo("Orcish Lumberjack", 142, Rarity.COMMON, mage.cards.o.OrcishLumberjack.class)); + cards.add(new SetCardInfo("Orcish Squatters", 143, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); cards.add(new SetCardInfo("Orcish Veteran", 144, Rarity.COMMON, OrcishVeteran.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 25, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 26, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); From fd1649c9e72ac2afb94fe4ae5c8f0ebc8d0ce97b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 16:27:18 -0400 Subject: [PATCH 33/68] Implemented Earthlink --- Mage.Sets/src/mage/cards/e/Earthlink.java | 106 ++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 108 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/Earthlink.java diff --git a/Mage.Sets/src/mage/cards/e/Earthlink.java b/Mage.Sets/src/mage/cards/e/Earthlink.java new file mode 100644 index 0000000000..ea985d210e --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/Earthlink.java @@ -0,0 +1,106 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class Earthlink extends CardImpl { + + public Earthlink(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{R}{G}"); + + // At the beginning of your upkeep, sacrifice Earthlink unless you pay {2}. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{2}")), TargetController.YOU, false)); + + // Whenever a creature dies, that creature's controller sacrifices a land. + this.addAbility(new DiesCreatureTriggeredAbility(new EarthlinkEffect(), false, false, true)); + } + + public Earthlink(final Earthlink card) { + super(card); + } + + @Override + public Earthlink copy() { + return new Earthlink(this); + } +} + +class EarthlinkEffect extends OneShotEffect { + + public EarthlinkEffect() { + super(Outcome.DrawCard); + this.staticText = "that creature's controller sacrifices a land"; + } + + public EarthlinkEffect(final EarthlinkEffect effect) { + super(effect); + } + + @Override + public EarthlinkEffect copy() { + return new EarthlinkEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = (Permanent) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.BATTLEFIELD); + if (permanent != null) { + Player controller = game.getPlayer(permanent.getControllerId()); + if (controller != null) { + Effect effect = new SacrificeEffect(StaticFilters.FILTER_LAND, 1, "that creature's controller"); + effect.setTargetPointer(new FixedTarget(controller.getId(), game)); + effect.apply(game, source); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 2fea7b8b4c..50574bfb56 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -107,6 +107,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Disenchant", 244, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Drift of the Dead", 11, Rarity.UNCOMMON, mage.cards.d.DriftOfTheDead.class)); cards.add(new SetCardInfo("Dwarven Armory", 182, Rarity.RARE, mage.cards.d.DwarvenArmory.class)); + cards.add(new SetCardInfo("Earthlink", 363, Rarity.RARE, mage.cards.e.Earthlink.class)); cards.add(new SetCardInfo("Elder Druid", 120, Rarity.RARE, mage.cards.e.ElderDruid.class)); cards.add(new SetCardInfo("Elemental Augury", 364, Rarity.RARE, mage.cards.e.ElementalAugury.class)); cards.add(new SetCardInfo("Enduring Renewal", 247, Rarity.RARE, mage.cards.e.EnduringRenewal.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index a762138985..9162d24149 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -109,6 +109,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Drift of the Dead", 86, Rarity.COMMON, mage.cards.d.DriftOfTheDead.class)); cards.add(new SetCardInfo("Dwarven Ruins", 227, Rarity.UNCOMMON, mage.cards.d.DwarvenRuins.class)); cards.add(new SetCardInfo("Dystopia", 88, Rarity.RARE, mage.cards.d.Dystopia.class)); + cards.add(new SetCardInfo("Earthlink", 192, Rarity.RARE, mage.cards.e.Earthlink.class)); cards.add(new SetCardInfo("Ebon Praetor", 89, Rarity.RARE, mage.cards.e.EbonPraetor.class)); cards.add(new SetCardInfo("Ebon Stronghold", 228, Rarity.UNCOMMON, mage.cards.e.EbonStronghold.class)); cards.add(new SetCardInfo("Elemental Augury", 193, Rarity.RARE, mage.cards.e.ElementalAugury.class)); From 199bba11c4695f5e827e676d476eca2ed134e1f2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 16:47:17 -0400 Subject: [PATCH 34/68] Implemented Snow Fortress --- Mage.Sets/src/mage/cards/s/SnowFortress.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SnowFortress.java diff --git a/Mage.Sets/src/mage/cards/s/SnowFortress.java b/Mage.Sets/src/mage/cards/s/SnowFortress.java new file mode 100644 index 0000000000..7ec925286b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SnowFortress.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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class SnowFortress extends CardImpl { + + private static final SnowFortressFilter filter = new SnowFortressFilter(); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + + public SnowFortress(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + + this.subtype.add(SubType.WALL); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // {1}: Snow Fortress gets +1/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(1))); + + // {1}: Snow Fortress gets +0/+1 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(0, 1, Duration.EndOfTurn), new GenericManaCost(1))); + + // {3}: Snow Fortress deals 1 damage to target creature without flying that's attacking you. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new GenericManaCost(3)); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public SnowFortress(final SnowFortress card) { + super(card); + } + + @Override + public SnowFortress copy() { + return new SnowFortress(this); + } +} + +class SnowFortressFilter extends FilterAttackingCreature { + + public SnowFortressFilter() { + super("creature without flying that's attacking you"); + } + + public SnowFortressFilter(final SnowFortressFilter filter) { + super(filter); + } + + @Override + public SnowFortressFilter copy() { + return new SnowFortressFilter(this); + } + + @Override + public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { + return super.match(permanent, sourceId, playerId, game) + && permanent.isAttacking() // to prevent unneccessary combat checking if not attacking + && playerId.equals(game.getCombat().getDefenderId(permanent.getId())); + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 50574bfb56..2c472c5a19 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -269,6 +269,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Silver Erne", 98, Rarity.UNCOMMON, mage.cards.s.SilverErne.class)); cards.add(new SetCardInfo("Skeleton Ship", 379, Rarity.RARE, mage.cards.s.SkeletonShip.class)); cards.add(new SetCardInfo("Skull Catapult", 311, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); + cards.add(new SetCardInfo("Snow Fortress", 312, Rarity.RARE, mage.cards.s.SnowFortress.class)); cards.add(new SetCardInfo("Snow-Covered Forest", 347, Rarity.COMMON, mage.cards.s.SnowCoveredForest.class)); cards.add(new SetCardInfo("Snow-Covered Island", 348, Rarity.COMMON, mage.cards.s.SnowCoveredIsland.class)); cards.add(new SetCardInfo("Snow-Covered Mountain", 349, Rarity.COMMON, mage.cards.s.SnowCoveredMountain.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 9162d24149..bf4477c6b9 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -214,6 +214,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Sibilant Spirit", 67, Rarity.RARE, mage.cards.s.SibilantSpirit.class)); cards.add(new SetCardInfo("Skeleton Ship", 197, Rarity.RARE, mage.cards.s.SkeletonShip.class)); cards.add(new SetCardInfo("Skull Catapult", 219, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); + cards.add(new SetCardInfo("Snow Fortress", 220, Rarity.UNCOMMON, mage.cards.s.SnowFortress.class)); cards.add(new SetCardInfo("Snow-Covered Forest", 245, Rarity.LAND, mage.cards.s.SnowCoveredForest.class)); cards.add(new SetCardInfo("Snow-Covered Island", 242, Rarity.LAND, mage.cards.s.SnowCoveredIsland.class)); cards.add(new SetCardInfo("Snow-Covered Mountain", 244, Rarity.LAND, mage.cards.s.SnowCoveredMountain.class)); From c6dd9270eaee2a33f83d13695726a3746405ca2e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 17:52:04 -0400 Subject: [PATCH 35/68] Implemented Soldevi Golem --- Mage.Sets/src/mage/cards/s/SoldeviGolem.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionIV.java | 2 + 3 files changed, 90 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoldeviGolem.java diff --git a/Mage.Sets/src/mage/cards/s/SoldeviGolem.java b/Mage.Sets/src/mage/cards/s/SoldeviGolem.java new file mode 100644 index 0000000000..35b3d151c2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoldeviGolem.java @@ -0,0 +1,87 @@ +/* + * 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.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SoldeviGolem extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(new TappedPredicate()); + } + + public SoldeviGolem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add(SubType.GOLEM); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Soldevi Golem doesn't untap during your untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); + + // At the beginning of your upkeep, you may untap target tapped creature an opponent controls. If you do, untap Soldevi Golem. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new UntapTargetEffect().setText("untap target tapped creature an opponent controls."), TargetController.YOU, true); + ability.addEffect(new UntapSourceEffect().setText("If you do, untap {this}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public SoldeviGolem(final SoldeviGolem card) { + super(card); + } + + @Override + public SoldeviGolem copy() { + return new SoldeviGolem(this); + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 2c472c5a19..bfa45f9f77 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -276,6 +276,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Snow-Covered Plains", 350, Rarity.COMMON, mage.cards.s.SnowCoveredPlains.class)); cards.add(new SetCardInfo("Snow-Covered Swamp", 351, Rarity.COMMON, mage.cards.s.SnowCoveredSwamp.class)); cards.add(new SetCardInfo("Snow Hound", 277, Rarity.UNCOMMON, mage.cards.s.SnowHound.class)); + cards.add(new SetCardInfo("Soldevi Golem", 313, Rarity.RARE, mage.cards.s.SoldeviGolem.class)); cards.add(new SetCardInfo("Soldevi Machinist", 102, Rarity.UNCOMMON, mage.cards.s.SoldeviMachinist.class)); cards.add(new SetCardInfo("Soldevi Simulacrum", 314, Rarity.UNCOMMON, mage.cards.s.SoldeviSimulacrum.class)); cards.add(new SetCardInfo("Songs of the Damned", 48, Rarity.COMMON, mage.cards.s.SongsOfTheDamned.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index 98a584a423..fb08716493 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -241,8 +241,10 @@ public class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Sinkhole", 97, Rarity.RARE, mage.cards.s.Sinkhole.class)); cards.add(new SetCardInfo("Sleight of Hand", 62, Rarity.COMMON, mage.cards.s.SleightOfHand.class)); cards.add(new SetCardInfo("Smoke", 137, Rarity.RARE, mage.cards.s.Smoke.class)); + cards.add(new SetCardInfo("Soldevi Golem", 228, Rarity.UNCOMMON, mage.cards.s.SoldeviGolem.class)); cards.add(new SetCardInfo("Soldevi Machinist", 63, Rarity.UNCOMMON, mage.cards.s.SoldeviMachinist.class)); cards.add(new SetCardInfo("Sol Ring", 227, Rarity.RARE, mage.cards.s.SolRing.class)); + cards.add(new SetCardInfo("Soldevi Golem", 228, Rarity.UNCOMMON, mage.cards.s.SoldeviGolem.class)); cards.add(new SetCardInfo("Soul Shred", 98, Rarity.COMMON, mage.cards.s.SoulShred.class)); cards.add(new SetCardInfo("Southern Elephant", 167, Rarity.COMMON, mage.cards.s.SouthernElephant.class)); cards.add(new SetCardInfo("Spotted Griffin", 28, Rarity.COMMON, mage.cards.s.SpottedGriffin.class)); From 165d56d2dbfb624a5af4001fc8d1d61b27862174 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 18:01:02 -0400 Subject: [PATCH 36/68] Implemented Labyrinth Minotaur --- .../src/mage/cards/l/LabyrinthMinotaur.java | 64 +++++++++++++++++++ Mage.Sets/src/mage/sets/FifthEdition.java | 1 + Mage.Sets/src/mage/sets/Homelands.java | 1 + .../src/mage/sets/MastersEditionIII.java | 1 + 4 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LabyrinthMinotaur.java diff --git a/Mage.Sets/src/mage/cards/l/LabyrinthMinotaur.java b/Mage.Sets/src/mage/cards/l/LabyrinthMinotaur.java new file mode 100644 index 0000000000..bb0eddadc4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LabyrinthMinotaur.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.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class LabyrinthMinotaur extends CardImpl { + + public LabyrinthMinotaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.MINOTAUR); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Whenever Labyrinth Minotaur blocks a creature, that creature doesn't untap during its controller's next untap step. + this.addAbility(new BlocksTriggeredAbility(new DontUntapInControllersNextUntapStepTargetEffect("that creature"), false, true)); + } + + public LabyrinthMinotaur(final LabyrinthMinotaur card) { + super(card); + } + + @Override + public LabyrinthMinotaur copy() { + return new LabyrinthMinotaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index d2247f8bf0..ec8633bbe7 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -252,6 +252,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Knight of Stromgald", 33, Rarity.UNCOMMON, mage.cards.k.KnightOfStromgald.class)); cards.add(new SetCardInfo("Krovikan Fetish", 34, Rarity.COMMON, mage.cards.k.KrovikanFetish.class)); cards.add(new SetCardInfo("Krovikan Sorcerer", 96, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class)); + cards.add(new SetCardInfo("Labyrinth Minotaur", 97, Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class)); cards.add(new SetCardInfo("Leshrac's Rite", 35, Rarity.UNCOMMON, mage.cards.l.LeshracsRite.class)); cards.add(new SetCardInfo("Leviathan", 98, Rarity.RARE, mage.cards.l.Leviathan.class)); cards.add(new SetCardInfo("Ley Druid", 170, Rarity.COMMON, mage.cards.l.LeyDruid.class)); diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 8414264539..16465d7e0b 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -131,6 +131,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Joven", 97, Rarity.COMMON, mage.cards.j.Joven.class)); cards.add(new SetCardInfo("Koskun Falls", 18, Rarity.RARE, mage.cards.k.KoskunFalls.class)); cards.add(new SetCardInfo("Koskun Keep", 139, Rarity.UNCOMMON, mage.cards.k.KoskunKeep.class)); + cards.add(new SetCardInfo("Labyrinth Minotaur", 38, Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class)); cards.add(new SetCardInfo("Leaping Lizard", 63, Rarity.COMMON, mage.cards.l.LeapingLizard.class)); cards.add(new SetCardInfo("Leeches", 111, Rarity.RARE, mage.cards.l.Leeches.class)); cards.add(new SetCardInfo("Marjhan", 39, Rarity.RARE, mage.cards.m.Marjhan.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index 5d732eceba..18631aad73 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -154,6 +154,7 @@ public class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Kobolds of Kher Keep", 107, Rarity.COMMON, mage.cards.k.KoboldsOfKherKeep.class)); cards.add(new SetCardInfo("Kobold Taskmaster", 106, Rarity.COMMON, mage.cards.k.KoboldTaskmaster.class)); cards.add(new SetCardInfo("Kongming, 'Sleeping Dragon'", 16, Rarity.RARE, mage.cards.k.KongmingSleepingDragon.class)); + cards.add(new SetCardInfo("Labyrinth Minotaur", 39, Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class)); cards.add(new SetCardInfo("Lady Caleria", 157, Rarity.UNCOMMON, mage.cards.l.LadyCaleria.class)); cards.add(new SetCardInfo("Lady Evangela", 158, Rarity.UNCOMMON, mage.cards.l.LadyEvangela.class)); cards.add(new SetCardInfo("Lady Orca", 159, Rarity.COMMON, mage.cards.l.LadyOrca.class)); From e1e5b8a936cf12a52c4dc685ae6a1d5f749a2cec Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 18:13:48 -0400 Subject: [PATCH 37/68] Implemented Disharmony --- Mage.Sets/src/mage/cards/d/Disharmony.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Legends.java | 1 + .../src/mage/sets/MastersEditionIII.java | 1 + 3 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/Disharmony.java diff --git a/Mage.Sets/src/mage/cards/d/Disharmony.java b/Mage.Sets/src/mage/cards/d/Disharmony.java new file mode 100644 index 0000000000..42d58c00a5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Disharmony.java @@ -0,0 +1,70 @@ +/* + * 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.d; + +import java.util.UUID; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.BeforeBlockersAreDeclaredCondition; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TurnPhase; +import mage.target.common.TargetAttackingCreature; + +/** + * + * @author TheElk801 + */ +public class Disharmony extends CardImpl { + + public Disharmony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); + + // Cast Disharmony only during combat before blockers are declared. + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, BeforeBlockersAreDeclaredCondition.instance)); + + // Untap target attacking creature and remove it from combat. Gain control of that creature until end of turn. + this.getSpellAbility().addEffect(new UntapTargetEffect()); + this.getSpellAbility().addEffect(new RemoveFromCombatTargetEffect().setText("and remove it from combat.")); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn, true).setText("Gain control of that creature until end of turn.")); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public Disharmony(final Disharmony card) { + super(card); + } + + @Override + public Disharmony copy() { + return new Disharmony(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index e0a7f3f724..46097a7576 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -101,6 +101,7 @@ public class Legends extends ExpansionSet { cards.add(new SetCardInfo("D'Avenant Archer", 176, Rarity.COMMON, mage.cards.d.DAvenantArcher.class)); cards.add(new SetCardInfo("Demonic Torment", 9, Rarity.UNCOMMON, mage.cards.d.DemonicTorment.class)); cards.add(new SetCardInfo("Devouring Deep", 50, Rarity.COMMON, mage.cards.d.DevouringDeep.class)); + cards.add(new SetCardInfo("Disharmony", 140, Rarity.RARE, mage.cards.d.Disharmony.class)); cards.add(new SetCardInfo("Divine Intervention", 177, Rarity.RARE, mage.cards.d.DivineIntervention.class)); cards.add(new SetCardInfo("Divine Offering", 178, Rarity.COMMON, mage.cards.d.DivineOffering.class)); cards.add(new SetCardInfo("Divine Transformation", 179, Rarity.RARE, mage.cards.d.DivineTransformation.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index 18631aad73..a46ec0ceb0 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -100,6 +100,7 @@ public class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Desperate Charge", 63, Rarity.COMMON, mage.cards.d.DesperateCharge.class)); cards.add(new SetCardInfo("Didgeridoo", 194, Rarity.UNCOMMON, mage.cards.d.Didgeridoo.class)); cards.add(new SetCardInfo("Disenchant", 7, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Disharmony", 95, Rarity.UNCOMMON, mage.cards.d.Disharmony.class)); cards.add(new SetCardInfo("Divine Intervention", 8, Rarity.RARE, mage.cards.d.DivineIntervention.class)); cards.add(new SetCardInfo("Dong Zhou, the Tyrant", 96, Rarity.RARE, mage.cards.d.DongZhouTheTyrant.class)); cards.add(new SetCardInfo("Elves of Deep Shadow", 116, Rarity.COMMON, mage.cards.e.ElvesOfDeepShadow.class)); From 8c20861e928e5595546d8cbda4c2d9fb76bbda3f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 18:32:46 -0400 Subject: [PATCH 38/68] Implemented Kjeldoran Home Guard --- .../src/mage/cards/k/KjeldoranHomeGuard.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Alliances.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + .../game/permanent/token/DeserterToken.java | 48 ++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KjeldoranHomeGuard.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/DeserterToken.java diff --git a/Mage.Sets/src/mage/cards/k/KjeldoranHomeGuard.java b/Mage.Sets/src/mage/cards/k/KjeldoranHomeGuard.java new file mode 100644 index 0000000000..0826886319 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KjeldoranHomeGuard.java @@ -0,0 +1,77 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.condition.common.AttackedOrBlockedThisCombatSourceCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.BoostCounter; +import mage.game.permanent.token.DeserterToken; +import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; + +/** + * + * @author TheElk801 + */ +public class KjeldoranHomeGuard extends CardImpl { + + public KjeldoranHomeGuard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(6); + + // At end of combat, if Kjeldoran Home Guard attacked or blocked this combat, put a -0/-1 counter on Kjeldoran Home Guard and put a 0/1 white Deserter creature token onto the battlefield. + Ability ability = new ConditionalTriggeredAbility( + new EndOfCombatTriggeredAbility(new AddCountersSourceEffect(new BoostCounter(0, -1)), false), + AttackedOrBlockedThisCombatSourceCondition.instance, + "At end of combat, if {this} attacked or blocked this combat, put a -0/-1 counter on {this} and create a 0/1 white Deserter creature token."); + ability.addEffect(new CreateTokenEffect(new DeserterToken()).setText("and create a 0/1 white Deserter creature token.")); + this.addAbility(ability, new AttackedOrBlockedThisCombatWatcher()); + } + + public KjeldoranHomeGuard(final KjeldoranHomeGuard card) { + super(card); + } + + @Override + public KjeldoranHomeGuard copy() { + return new KjeldoranHomeGuard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 63f105b8bf..83f5324d81 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -99,6 +99,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Juniper Order Advocate", 132, Rarity.UNCOMMON, mage.cards.j.JuniperOrderAdvocate.class)); cards.add(new SetCardInfo("Kaysa", 80, Rarity.RARE, mage.cards.k.Kaysa.class)); cards.add(new SetCardInfo("Keeper of Tresserhorn", 14, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); + cards.add(new SetCardInfo("Kjeldoran Home Guard", 135, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 184, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); cards.add(new SetCardInfo("Lake of the Dead", 185, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); cards.add(new SetCardInfo("Library of Lat-Nam", 47, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index bf4477c6b9..d1514a1a4f 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -162,6 +162,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Karplusan Giant", 133, Rarity.UNCOMMON, mage.cards.k.KarplusanGiant.class)); cards.add(new SetCardInfo("Kaysa", 170, Rarity.RARE, mage.cards.k.Kaysa.class)); cards.add(new SetCardInfo("Kjeldoran Dead", 98, Rarity.COMMON, mage.cards.k.KjeldoranDead.class)); + cards.add(new SetCardInfo("Kjeldoran Home Guard", 22, Rarity.UNCOMMON, mage.cards.k.KjeldoranHomeGuard.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 233, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class)); cards.add(new SetCardInfo("Knight of Stromgald", 99, Rarity.UNCOMMON, mage.cards.k.KnightOfStromgald.class)); cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/DeserterToken.java b/Mage/src/main/java/mage/game/permanent/token/DeserterToken.java new file mode 100644 index 0000000000..ec4daf2b44 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DeserterToken.java @@ -0,0 +1,48 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.constants.SubType; +import mage.MageInt; + +/** + * + * @author spjspj + */ +public class DeserterToken extends Token { + + public DeserterToken() { + super("Deserter", "0/1 white Deserter creature token"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add(SubType.DESERTER); + power = new MageInt(0); + toughness = new MageInt(1); + } +} From 297d662a8ce6e6115a769f9acff2b0b53e4d6e5e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 18:53:06 -0400 Subject: [PATCH 39/68] Implemented Ashen Ghoul --- Mage.Sets/src/mage/cards/a/AshenGhoul.java | 116 ++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AshenGhoul.java diff --git a/Mage.Sets/src/mage/cards/a/AshenGhoul.java b/Mage.Sets/src/mage/cards/a/AshenGhoul.java new file mode 100644 index 0000000000..243529325d --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AshenGhoul.java @@ -0,0 +1,116 @@ +/* + * 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.MageInt; +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.constants.SubType; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class AshenGhoul extends CardImpl { + + public AshenGhoul(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // {B}: Return Ashen Ghoul from your graveyard to the battlefield. Activate this ability only during your upkeep and only if three or more creature cards are above Ashen Ghoul. + this.addAbility(new ConditionalActivatedAbility( + Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToBattlefieldEffect(), + new ManaCostsImpl("{B}"), + AshenGhoulCondition.instance + )); + } + + public AshenGhoul(final AshenGhoul card) { + super(card); + } + + @Override + public AshenGhoul copy() { + return new AshenGhoul(this); + } +} + +enum AshenGhoulCondition implements Condition { + + instance; + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (!game.getStep().getType().equals(PhaseStep.UPKEEP) + || !game.getActivePlayerId().equals(source.getControllerId())) { + return false; + } + if (controller != null) { + int cardsAbove = 0; + boolean aboveCards = false; + for (Card card : controller.getGraveyard().getCards(game)) { + if (aboveCards && card.isCreature()) { + cardsAbove++; + if (cardsAbove > 2) { + return true; + } + } + if (card.getId().equals(source.getSourceId())) { + aboveCards = true; + } + } + } + return false; + } + + @Override + public String toString() { + return "three or more creature cards are above {this}"; + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index bfa45f9f77..9c28934691 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -61,6 +61,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Arenson's Aura", 227, Rarity.COMMON, mage.cards.a.ArensonsAura.class)); cards.add(new SetCardInfo("Armor of Faith", 228, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class)); cards.add(new SetCardInfo("Arnjlot's Ascent", 57, Rarity.COMMON, mage.cards.a.ArnjlotsAscent.class)); + cards.add(new SetCardInfo("Ashen Ghoul", 2, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); cards.add(new SetCardInfo("Aurochs", 113, Rarity.COMMON, mage.cards.a.Aurochs.class)); cards.add(new SetCardInfo("Avalanche", 171, Rarity.UNCOMMON, mage.cards.a.Avalanche.class)); cards.add(new SetCardInfo("Balduvian Barbarians", 172, Rarity.COMMON, mage.cards.b.BalduvianBarbarians.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index d1514a1a4f..12dda96464 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -76,6 +76,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Armored Griffin", 5, Rarity.COMMON, mage.cards.a.ArmoredGriffin.class)); cards.add(new SetCardInfo("Armor of Faith", 4, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class)); cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, ArmorThrull.class)); + cards.add(new SetCardInfo("Ashen Ghoul", 78, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); cards.add(new SetCardInfo("Aurochs", 153, Rarity.COMMON, mage.cards.a.Aurochs.class)); cards.add(new SetCardInfo("Aysen Bureaucrats", 6, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class)); cards.add(new SetCardInfo("Aysen Crusader", 7, Rarity.UNCOMMON, mage.cards.a.AysenCrusader.class)); From 8bf3d5a86513169bb766510226d69c7706cb692b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 4 Oct 2017 23:18:01 -0400 Subject: [PATCH 40/68] Implemented Aku Djinn --- Mage.Sets/src/mage/cards/a/AkuDjinn.java | 78 ++++++++++++++++++++++++ Mage.Sets/src/mage/sets/Visions.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AkuDjinn.java diff --git a/Mage.Sets/src/mage/cards/a/AkuDjinn.java b/Mage.Sets/src/mage/cards/a/AkuDjinn.java new file mode 100644 index 0000000000..b3c3faf92e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AkuDjinn.java @@ -0,0 +1,78 @@ +/* + * 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.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.constants.SubType; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class AkuDjinn extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature each opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public AkuDjinn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.DJINN); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // At the beginning of your upkeep, put a +1/+1 counter on each creature each opponent controls. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), TargetController.YOU, false)); + } + + public AkuDjinn(final AkuDjinn card) { + super(card); + } + + @Override + public AkuDjinn copy() { + return new AkuDjinn(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 8486c34d00..b99cd5d07d 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -54,6 +54,7 @@ public class Visions extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Aku Djinn", 1, Rarity.RARE, mage.cards.a.AkuDjinn.class)); cards.add(new SetCardInfo("Anvil of Bogardan", 141, Rarity.RARE, mage.cards.a.AnvilOfBogardan.class)); cards.add(new SetCardInfo("Archangel", 101, Rarity.RARE, mage.cards.a.Archangel.class)); cards.add(new SetCardInfo("Army Ants", 126, Rarity.UNCOMMON, mage.cards.a.ArmyAnts.class)); From d85ac7f641f57322061156307e170421c8132d0f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 09:46:09 -0400 Subject: [PATCH 41/68] Implemented Wave of Terror --- Mage.Sets/src/mage/cards/w/WaveOfTerror.java | 104 +++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 105 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WaveOfTerror.java diff --git a/Mage.Sets/src/mage/cards/w/WaveOfTerror.java b/Mage.Sets/src/mage/cards/w/WaveOfTerror.java new file mode 100644 index 0000000000..53747b4366 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WaveOfTerror.java @@ -0,0 +1,104 @@ +/* + * 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.abilities.Ability; +import mage.abilities.common.BeginningOfDrawTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class WaveOfTerror extends CardImpl { + + public WaveOfTerror(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // At the beginning of your draw step, destroy each creature with converted mana cost equal to the number of age counters on Wave of Terror. They can't be regenerated. + this.addAbility(new BeginningOfDrawTriggeredAbility(new WaveOfTerrorEffect(), TargetController.YOU, false)); + } + + public WaveOfTerror(final WaveOfTerror card) { + super(card); + } + + @Override + public WaveOfTerror copy() { + return new WaveOfTerror(this); + } +} + +class WaveOfTerrorEffect extends OneShotEffect { + + WaveOfTerrorEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy each creature with converted mana cost equal to the number of age counters on {this}. They can't be regenerated."; + } + + WaveOfTerrorEffect(final WaveOfTerrorEffect effect) { + super(effect); + } + + @Override + public WaveOfTerrorEffect copy() { + return new WaveOfTerrorEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (permanent == null) { + return false; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ConvertedManaCostPredicate( + ComparisonType.EQUAL_TO, + permanent.getCounters(game).getCount(CounterType.AGE) + )); + return new DestroyAllEffect(filter, true).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index b7acb91331..91f37aeed8 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -193,6 +193,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Veteran Explorer", 86, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vitalize", 87, Rarity.COMMON, mage.cards.v.Vitalize.class)); cards.add(new SetCardInfo("Vodalian Illusionist", 58, Rarity.UNCOMMON, mage.cards.v.VodalianIllusionist.class)); + cards.add(new SetCardInfo("Wave of Terror", 28, Rarity.RARE, mage.cards.w.WaveOfTerror.class)); cards.add(new SetCardInfo("Well of Knowledge", 162, Rarity.RARE, mage.cards.w.WellOfKnowledge.class)); cards.add(new SetCardInfo("Winding Canyons", 167, Rarity.RARE, mage.cards.w.WindingCanyons.class)); cards.add(new SetCardInfo("Xanthic Statue", 163, Rarity.RARE, mage.cards.x.XanthicStatue.class)); From 9719d5eed5d8a9896102aa6d2f04abb2b0ecb272 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 09:54:56 -0400 Subject: [PATCH 42/68] Implemented Timid Drake --- Mage.Sets/src/mage/cards/t/TimidDrake.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/MercadianMasques.java | 1 + Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 3 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TimidDrake.java diff --git a/Mage.Sets/src/mage/cards/t/TimidDrake.java b/Mage.Sets/src/mage/cards/t/TimidDrake.java new file mode 100644 index 0000000000..b1cd6e3fac --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TimidDrake.java @@ -0,0 +1,80 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class TimidDrake extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public TimidDrake(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.DRAKE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When another creature enters the battlefield, return Timid Drake to its owner's hand. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), filter, false, + "When another creature enters the battlefield, return {this} to its owner's hand." + )); + } + + public TimidDrake(final TimidDrake card) { + super(card); + } + + @Override + public TimidDrake copy() { + return new TimidDrake(this); + } +} diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index 61f5f54a90..d8ceae0219 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -329,6 +329,7 @@ public class MercadianMasques extends ExpansionSet { cards.add(new SetCardInfo("Tidal Bore", 109, Rarity.COMMON, mage.cards.t.TidalBore.class)); cards.add(new SetCardInfo("Tidal Kraken", 110, Rarity.RARE, mage.cards.t.TidalKraken.class)); cards.add(new SetCardInfo("Tiger Claws", 279, Rarity.COMMON, mage.cards.t.TigerClaws.class)); + cards.add(new SetCardInfo("Timid Drake", 111, Rarity.UNCOMMON, mage.cards.t.TimidDrake.class)); cards.add(new SetCardInfo("Tonic Peddler", 54, Rarity.UNCOMMON, mage.cards.t.TonicPeddler.class)); cards.add(new SetCardInfo("Tooth of Ramos", 313, Rarity.RARE, mage.cards.t.ToothOfRamos.class)); cards.add(new SetCardInfo("Tower of the Magistrate", 330, Rarity.RARE, mage.cards.t.TowerOfTheMagistrate.class)); diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index 91f37aeed8..1944af285a 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -183,6 +183,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Tendrils of Despair", 25, Rarity.COMMON, mage.cards.t.TendrilsOfDespair.class)); cards.add(new SetCardInfo("Thunderbolt", 115, Rarity.COMMON, mage.cards.t.Thunderbolt.class)); cards.add(new SetCardInfo("Thundermare", 116, Rarity.RARE, mage.cards.t.Thundermare.class)); + cards.add(new SetCardInfo("Timid Drake", 54, Rarity.UNCOMMON, mage.cards.t.TimidDrake.class)); cards.add(new SetCardInfo("Tolarian Drake", 55, Rarity.COMMON, mage.cards.t.TolarianDrake.class)); cards.add(new SetCardInfo("Tolarian Entrancer", 56, Rarity.RARE, mage.cards.t.TolarianEntrancer.class)); cards.add(new SetCardInfo("Tolarian Serpent", 57, Rarity.RARE, mage.cards.t.TolarianSerpent.class)); From 0c4b33c65d8c30493f56f5ef05511347d5467d71 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 10:04:16 -0400 Subject: [PATCH 43/68] Implemented Urborg Stalker --- Mage.Sets/src/mage/cards/u/UrborgStalker.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/u/UrborgStalker.java diff --git a/Mage.Sets/src/mage/cards/u/UrborgStalker.java b/Mage.Sets/src/mage/cards/u/UrborgStalker.java new file mode 100644 index 0000000000..1f4765e21f --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UrborgStalker.java @@ -0,0 +1,87 @@ +/* + * 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.u; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class UrborgStalker extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + } + + public UrborgStalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HORROR); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // At the beginning of each player's upkeep, if that player controls a nonblack, nonland permanent, Urborg Stalker deals 1 damage to that player. + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility(new DamageTargetEffect(1), TargetController.ANY, false), + new PermanentsOnTheBattlefieldCondition(filter), + "At the beginning of each player's upkeep, " + + "if that player controls a nonblack, nonland permanent, " + + "{this} deals 1 damage to that player." + )); + } + + public UrborgStalker(final UrborgStalker card) { + super(card); + } + + @Override + public UrborgStalker copy() { + return new UrborgStalker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index 1944af285a..6a6ad36742 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -191,6 +191,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Tranquil Grove", 84, Rarity.RARE, mage.cards.t.TranquilGrove.class)); cards.add(new SetCardInfo("Uktabi Efreet", 85, Rarity.COMMON, mage.cards.u.UktabiEfreet.class)); cards.add(new SetCardInfo("Urborg Justice", 26, Rarity.RARE, mage.cards.u.UrborgJustice.class)); + cards.add(new SetCardInfo("Urborg Stalker", 27, Rarity.RARE, mage.cards.u.UrborgStalker.class)); cards.add(new SetCardInfo("Veteran Explorer", 86, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vitalize", 87, Rarity.COMMON, mage.cards.v.Vitalize.class)); cards.add(new SetCardInfo("Vodalian Illusionist", 58, Rarity.UNCOMMON, mage.cards.v.VodalianIllusionist.class)); From bff10480273f0d2d2b02f9d52e0338ef453d38be Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 10:15:51 -0400 Subject: [PATCH 44/68] Implemented Thran Forge --- Mage.Sets/src/mage/cards/t/ThranForge.java | 83 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 84 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThranForge.java diff --git a/Mage.Sets/src/mage/cards/t/ThranForge.java b/Mage.Sets/src/mage/cards/t/ThranForge.java new file mode 100644 index 0000000000..b3a9c66ed1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThranForge.java @@ -0,0 +1,83 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class ThranForge extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT))); + } + + public ThranForge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // {2}: Until end of turn, target nonartifact creature gets +1/+0 and becomes an artifact in addition to its other types. + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostTargetEffect(1, 0, Duration.EndOfTurn) + .setText("Until end of turn, target nonartifact creature gets +1/+0"), + new GenericManaCost(2)); + ability.addEffect( + new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn) + .setText("and becomes an artifact in addition to its other types") + ); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public ThranForge(final ThranForge card) { + super(card); + } + + @Override + public ThranForge copy() { + return new ThranForge(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index 6a6ad36742..6d2f6558d7 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -181,6 +181,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Tariff", 144, Rarity.RARE, mage.cards.t.Tariff.class)); cards.add(new SetCardInfo("Teferi's Veil", 53, Rarity.UNCOMMON, mage.cards.t.TeferisVeil.class)); cards.add(new SetCardInfo("Tendrils of Despair", 25, Rarity.COMMON, mage.cards.t.TendrilsOfDespair.class)); + cards.add(new SetCardInfo("Thran Forge", 159, Rarity.UNCOMMON, mage.cards.t.ThranForge.class)); cards.add(new SetCardInfo("Thunderbolt", 115, Rarity.COMMON, mage.cards.t.Thunderbolt.class)); cards.add(new SetCardInfo("Thundermare", 116, Rarity.RARE, mage.cards.t.Thundermare.class)); cards.add(new SetCardInfo("Timid Drake", 54, Rarity.UNCOMMON, mage.cards.t.TimidDrake.class)); From 0cd11c4eb7c44f4806dd95171f64339373c6c29f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 10:48:06 -0400 Subject: [PATCH 45/68] Implemented Knight of the Mists --- .../src/mage/cards/k/KnightOfTheMists.java | 118 ++++++++++++++++++ Mage.Sets/src/mage/sets/Visions.java | 1 + 2 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KnightOfTheMists.java diff --git a/Mage.Sets/src/mage/cards/k/KnightOfTheMists.java b/Mage.Sets/src/mage/cards/k/KnightOfTheMists.java new file mode 100644 index 0000000000..79d74f9de5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KnightOfTheMists.java @@ -0,0 +1,118 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlankingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class KnightOfTheMists extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Knight"); + + static { + filter.add(new SubtypePredicate(SubType.KNIGHT)); + } + + public KnightOfTheMists(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flanking + this.addAbility(new FlankingAbility()); + + // When Knight of the Mists enters the battlefield, you may pay {U}. If you don't, destroy target Knight and it can't be regenerated. + Ability ability = new EntersBattlefieldTriggeredAbility(new KnightOfTheMistsEffect()); + ability.addTarget(new TargetCreaturePermanent(filter)); + } + + public KnightOfTheMists(final KnightOfTheMists card) { + super(card); + } + + @Override + public KnightOfTheMists copy() { + return new KnightOfTheMists(this); + } +} + +class KnightOfTheMistsEffect extends OneShotEffect { + + KnightOfTheMistsEffect() { + super(Outcome.Neutral); + this.staticText = "When {this} enters the battlefield, you may pay {U}. If you don't, destroy target Knight and it can't be regenerated."; + } + + KnightOfTheMistsEffect(final KnightOfTheMistsEffect effect) { + super(effect); + } + + @Override + public KnightOfTheMistsEffect copy() { + return new KnightOfTheMistsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getSourceId()); + if (player == null) { + return false; + } + Cost cost = new ManaCostsImpl("{U}"); + if (!(cost.canPay(source, source.getSourceId(), player.getId(), game) + && player.chooseUse(outcome, "Pay {U}?", source, game) + && cost.pay(source, game, source.getSourceId(), player.getId(), false))) { + return new DestroyTargetEffect(true).apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index b99cd5d07d..c5ca00bb6e 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -114,6 +114,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Keeper of Kookus", 85, Rarity.COMMON, mage.cards.k.KeeperOfKookus.class)); cards.add(new SetCardInfo("King Cheetah", 60, Rarity.COMMON, mage.cards.k.KingCheetah.class)); cards.add(new SetCardInfo("Knight of Valor", 111, Rarity.COMMON, mage.cards.k.KnightOfValor.class)); + cards.add(new SetCardInfo("Knight of the Mists", 36, Rarity.COMMON, mage.cards.k.KnightOfTheMists.class)); cards.add(new SetCardInfo("Kookus", 85, Rarity.RARE, mage.cards.k.Kookus.class)); cards.add(new SetCardInfo("Lead-Belly Chimera", 148, Rarity.UNCOMMON, mage.cards.l.LeadBellyChimera.class)); cards.add(new SetCardInfo("Lichenthrope", 62, Rarity.RARE, mage.cards.l.Lichenthrope.class)); From 5e37c1d93c14c5648a8657b0ae2a458a9824df50 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 12:49:52 -0400 Subject: [PATCH 46/68] Implemented Hopping Automaton --- .../src/mage/cards/h/HoppingAutomaton.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HoppingAutomaton.java diff --git a/Mage.Sets/src/mage/cards/h/HoppingAutomaton.java b/Mage.Sets/src/mage/cards/h/HoppingAutomaton.java new file mode 100644 index 0000000000..952ed10227 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HoppingAutomaton.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author TheElk801 + */ +public class HoppingAutomaton extends CardImpl { + + public HoppingAutomaton(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {0}: Hopping Automaton gets -1/-1 and gains flying until end of turn. + Effect effect = new BoostSourceEffect(-1, -1, Duration.EndOfTurn); + effect.setText("{this} gets -1/-1"); + Ability ability = new SimpleActivatedAbility(effect, new ManaCostsImpl("{0}")); + effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains flying until end of turn"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public HoppingAutomaton(final HoppingAutomaton card) { + super(card); + } + + @Override + public HoppingAutomaton copy() { + return new HoppingAutomaton(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 97611b2883..bda4d931a5 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -190,6 +190,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); + cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); cards.add(new SetCardInfo("Horseshoe Crab", 80, Rarity.COMMON, mage.cards.h.HorseshoeCrab.class)); cards.add(new SetCardInfo("Humble", 18, Rarity.UNCOMMON, mage.cards.h.Humble.class)); cards.add(new SetCardInfo("Hush", 266, Rarity.COMMON, mage.cards.h.Hush.class)); From 3b0b923b7ceaf1f8a8b294191350f860fbfe52ff Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 13:31:05 -0400 Subject: [PATCH 47/68] Implemented Weathered Bodyguards --- .../src/mage/cards/w/WeatheredBodyguards.java | 128 ++++++++++++++++++ Mage.Sets/src/mage/sets/TimeSpiral.java | 1 + .../java/mage/game/combat/CombatGroup.java | 4 + 3 files changed, 133 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java diff --git a/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java b/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java new file mode 100644 index 0000000000..f6dc7d6a98 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java @@ -0,0 +1,128 @@ +/* + * 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.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.events.DamagePlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class WeatheredBodyguards extends CardImpl { + + public WeatheredBodyguards(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // As long as Weathered Bodyguards is untapped, all combat damage that would be dealt to you by unblocked creatures is dealt to Weathered Bodyguards instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WeatheredBodyguardsEffect())); + + // Morph {3}{W} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{W}"))); + + } + + public WeatheredBodyguards(final WeatheredBodyguards card) { + super(card); + } + + @Override + public WeatheredBodyguards copy() { + return new WeatheredBodyguards(this); + } +} + +class WeatheredBodyguardsEffect extends ReplacementEffectImpl { + + WeatheredBodyguardsEffect() { + super(Duration.WhileOnBattlefield, Outcome.RedirectDamage); + staticText = "As long as {this} is untapped, all combat damage that would be dealt to you by unblocked creatures is dealt to {this} instead"; + } + + WeatheredBodyguardsEffect(final WeatheredBodyguardsEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + DamagePlayerEvent damageEvent = (DamagePlayerEvent) event; + Permanent damager = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId()); + Permanent p = game.getPermanent(source.getSourceId()); + boolean applyIt = false; + if (p != null && !p.isTapped() && damageEvent.isCombatDamage() && damager != null && damager.isAttacking()) { + for (CombatGroup cg : game.getCombat().getGroups()) { + if (cg.getAttackers().contains(damager.getId()) && !cg.getBlocked()) { + applyIt = true; + break; + } + } + if (applyIt) { + p.damage(damageEvent.getAmount(), event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable()); + } + return true; + } + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(source.getControllerId()); + } + + @Override + public WeatheredBodyguardsEffect copy() { + return new WeatheredBodyguardsEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/TimeSpiral.java b/Mage.Sets/src/mage/sets/TimeSpiral.java index 554f44cc66..645e5ec3d2 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiral.java +++ b/Mage.Sets/src/mage/sets/TimeSpiral.java @@ -307,6 +307,7 @@ public class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Volcanic Awakening", 186, Rarity.UNCOMMON, mage.cards.v.VolcanicAwakening.class)); cards.add(new SetCardInfo("Walk the Aeons", 93, Rarity.RARE, mage.cards.w.WalkTheAeons.class)); cards.add(new SetCardInfo("Watcher Sliver", 45, Rarity.COMMON, mage.cards.w.WatcherSliver.class)); + cards.add(new SetCardInfo("Weathered Bodyguards", 46, Rarity.RARE, mage.cards.w.WeatheredBodyguards.class)); cards.add(new SetCardInfo("Weatherseed Totem", 268, Rarity.UNCOMMON, mage.cards.w.WeatherseedTotem.class)); cards.add(new SetCardInfo("Wheel of Fate", 187, Rarity.RARE, mage.cards.w.WheelOfFate.class)); cards.add(new SetCardInfo("Wipe Away", 94, Rarity.UNCOMMON, mage.cards.w.WipeAway.class)); diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 3bab5e6305..fc40f7e958 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -655,6 +655,10 @@ public class CombatGroup implements Serializable, Copyable { this.blocked = blocked; } + public boolean getBlocked() { + return blocked; + } + @Override public CombatGroup copy() { return new CombatGroup(this); From 2733d736d51a3e0ca9df04b3b7d8e386e9f6bb4f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 13:35:42 -0400 Subject: [PATCH 48/68] fixed Curtain of Light targeting, updated how being unblocked is checked --- Mage.Sets/src/mage/cards/c/CurtainOfLight.java | 6 +++--- .../src/mage/cards/w/WeatheredBodyguards.java | 14 ++------------ .../predicate/permanent/BlockedPredicate.java | 8 +------- .../main/java/mage/game/permanent/Permanent.java | 2 ++ .../java/mage/game/permanent/PermanentImpl.java | 11 +++++++++++ 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CurtainOfLight.java b/Mage.Sets/src/mage/cards/c/CurtainOfLight.java index 6f7211f921..f7a762d49e 100644 --- a/Mage.Sets/src/mage/cards/c/CurtainOfLight.java +++ b/Mage.Sets/src/mage/cards/c/CurtainOfLight.java @@ -41,7 +41,7 @@ import mage.constants.TurnPhase; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.AttackingPredicate; -import mage.filter.predicate.permanent.BlockingPredicate; +import mage.filter.predicate.permanent.BlockedPredicate; import mage.game.Game; import mage.game.combat.CombatGroup; import mage.game.permanent.Permanent; @@ -58,11 +58,11 @@ public class CurtainOfLight extends CardImpl { static { filter.add(new AttackingPredicate()); - filter.add(Predicates.not(new BlockingPredicate())); + filter.add(Predicates.not(new BlockedPredicate())); } public CurtainOfLight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Cast Curtain of Light only during combat after blockers are declared. this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, AfterBlockersAreDeclaredCondition.instance)); diff --git a/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java b/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java index f6dc7d6a98..e346bf6de8 100644 --- a/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java +++ b/Mage.Sets/src/mage/cards/w/WeatheredBodyguards.java @@ -42,7 +42,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; -import mage.game.combat.CombatGroup; import mage.game.events.DamagePlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -95,17 +94,8 @@ class WeatheredBodyguardsEffect extends ReplacementEffectImpl { DamagePlayerEvent damageEvent = (DamagePlayerEvent) event; Permanent damager = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId()); Permanent p = game.getPermanent(source.getSourceId()); - boolean applyIt = false; - if (p != null && !p.isTapped() && damageEvent.isCombatDamage() && damager != null && damager.isAttacking()) { - for (CombatGroup cg : game.getCombat().getGroups()) { - if (cg.getAttackers().contains(damager.getId()) && !cg.getBlocked()) { - applyIt = true; - break; - } - } - if (applyIt) { - p.damage(damageEvent.getAmount(), event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable()); - } + if (p != null && !p.isTapped() && damageEvent.isCombatDamage() && damager != null && damager.isAttacking() && !damager.isBlocked(game)) { + p.damage(damageEvent.getAmount(), event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable()); return true; } return true; diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/BlockedPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/BlockedPredicate.java index 603d3ae6d7..198bf268c0 100644 --- a/Mage/src/main/java/mage/filter/predicate/permanent/BlockedPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/permanent/BlockedPredicate.java @@ -29,7 +29,6 @@ package mage.filter.predicate.permanent; import mage.filter.predicate.Predicate; import mage.game.Game; -import mage.game.combat.CombatGroup; import mage.game.permanent.Permanent; /** @@ -40,12 +39,7 @@ public class BlockedPredicate implements Predicate { @Override public boolean apply(Permanent input, Game game) { - for (CombatGroup combatGroup : game.getCombat().getGroups()) { - if (!combatGroup.getBlockers().isEmpty() && combatGroup.getAttackers().contains(input.getId())) { - return true; - } - } - return false; + return input.isBlocked(game); } @Override diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java index 68efe807b6..fedf9aad48 100644 --- a/Mage/src/main/java/mage/game/permanent/Permanent.java +++ b/Mage/src/main/java/mage/game/permanent/Permanent.java @@ -193,6 +193,8 @@ public interface Permanent extends Card, Controllable { boolean isAttacking(); + boolean isBlocked(Game game); + int getBlocking(); void setAttacking(boolean attacking); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 18babecc50..f4bd39bb1a 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -48,6 +48,7 @@ import mage.game.Game; import mage.game.GameState; import mage.game.ZoneChangeInfo; import mage.game.ZonesHandler; +import mage.game.combat.CombatGroup; import mage.game.command.CommandObject; import mage.game.events.*; import mage.game.events.GameEvent.EventType; @@ -509,6 +510,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return attacking; } + @Override + public boolean isBlocked(Game game) { + for (CombatGroup combatGroup : game.getCombat().getGroups()) { + if (combatGroup.getBlocked() && combatGroup.getAttackers().contains(this.getId())) { + return true; + } + } + return false; + } + @Override public int getBlocking() { return blocking; From 28c5137e75b57ea69949dd077b0e946ab5ccd572 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 17:06:59 -0400 Subject: [PATCH 49/68] Implemented Temper --- Mage.Sets/src/mage/cards/t/Temper.java | 145 ++++++++++++++++++++++++ Mage.Sets/src/mage/sets/Stronghold.java | 1 + 2 files changed, 146 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/Temper.java diff --git a/Mage.Sets/src/mage/cards/t/Temper.java b/Mage.Sets/src/mage/cards/t/Temper.java new file mode 100644 index 0000000000..7e004b5f95 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/Temper.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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class Temper extends CardImpl { + + public Temper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{W}"); + + // Prevent the next X damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature. + this.getSpellAbility().addEffect(new TemperPreventDamageTargetEffect(new ManacostVariableValue(), Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public Temper(final Temper card) { + super(card); + } + + @Override + public Temper copy() { + return new Temper(this); + } +} + +class TemperPreventDamageTargetEffect extends PreventionEffectImpl { + + private int amount; + private final DynamicValue dVal; + private boolean initialized; + + public TemperPreventDamageTargetEffect(DynamicValue dVal, Duration duration) { + super(duration); + this.initialized = false; + this.dVal = dVal; + staticText = "Prevent the next X damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature"; + } + + public TemperPreventDamageTargetEffect(final TemperPreventDamageTargetEffect effect) { + super(effect); + this.amount = effect.amount; + this.dVal = effect.dVal; + this.initialized = effect.initialized; + } + + @Override + public TemperPreventDamageTargetEffect copy() { + return new TemperPreventDamageTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + if (!initialized) { + amount = dVal.calculate(game, source, this); + initialized = true; + } + GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false); + if (!game.replaceEvent(preventEvent)) { + int prevented = 0; + if (event.getAmount() >= this.amount) { + int damage = amount; + event.setAmount(event.getAmount() - amount); + this.used = true; + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), damage)); + prevented = damage; + } else { + int damage = event.getAmount(); + event.setAmount(0); + amount -= damage; + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), damage)); + prevented = damage; + } + + // add counters now + if (prevented > 0) { + Permanent targetPermanent = game.getPermanent(source.getTargets().getFirstTarget()); + if (targetPermanent != null) { + targetPermanent.addCounters(CounterType.P1P1.createInstance(prevented), source, game); + game.informPlayers(new StringBuilder("Temper: Prevented ").append(prevented).append(" damage ").toString()); + game.informPlayers("Temper: Adding " + prevented + " +1/+1 counters to " + targetPermanent.getName()); + } + } + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!this.used && super.applies(event, source, game)) { + if (source.getTargets().getFirstTarget().equals(event.getTargetId())) { + return true; + } + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/Stronghold.java b/Mage.Sets/src/mage/sets/Stronghold.java index 8fa9340af5..a08e4c7440 100644 --- a/Mage.Sets/src/mage/sets/Stronghold.java +++ b/Mage.Sets/src/mage/sets/Stronghold.java @@ -165,6 +165,7 @@ public class Stronghold extends ExpansionSet { cards.add(new SetCardInfo("Stronghold Assassin", 21, Rarity.RARE, mage.cards.s.StrongholdAssassin.class)); cards.add(new SetCardInfo("Stronghold Taskmaster", 22, Rarity.UNCOMMON, mage.cards.s.StrongholdTaskmaster.class)); cards.add(new SetCardInfo("Sword of the Chosen", 135, Rarity.RARE, mage.cards.s.SwordOfTheChosen.class)); + cards.add(new SetCardInfo("Temper", 120, Rarity.UNCOMMON, mage.cards.t.Temper.class)); cards.add(new SetCardInfo("Tempting Licid", 72, Rarity.UNCOMMON, mage.cards.t.TemptingLicid.class)); cards.add(new SetCardInfo("Thalakos Deceiver", 45, Rarity.RARE, mage.cards.t.ThalakosDeceiver.class)); cards.add(new SetCardInfo("Tidal Surge", 46, Rarity.COMMON, mage.cards.t.TidalSurge.class)); From 9a5343dac3fef15588bc88a3ee889bb217ec0cfb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 17:11:04 -0400 Subject: [PATCH 50/68] Implemented Bonethorn Valesk --- .../src/mage/cards/b/BonethornValesk.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Scourge.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BonethornValesk.java diff --git a/Mage.Sets/src/mage/cards/b/BonethornValesk.java b/Mage.Sets/src/mage/cards/b/BonethornValesk.java new file mode 100644 index 0000000000..6af8e310eb --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BonethornValesk.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.TurnedFaceUpAllTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class BonethornValesk extends CardImpl { + + public BonethornValesk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Whenever a permanent is turned face up, Bonethorn Valesk deals 1 damage to target creature or player. + Ability ability = new TurnedFaceUpAllTriggeredAbility(new DamageTargetEffect(1), new FilterPermanent()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public BonethornValesk(final BonethornValesk card) { + super(card); + } + + @Override + public BonethornValesk copy() { + return new BonethornValesk(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Scourge.java b/Mage.Sets/src/mage/sets/Scourge.java index 3b0dc59554..d3462236f7 100644 --- a/Mage.Sets/src/mage/sets/Scourge.java +++ b/Mage.Sets/src/mage/sets/Scourge.java @@ -66,6 +66,7 @@ public class Scourge extends ExpansionSet { cards.add(new SetCardInfo("Aven Liberator", 4, Rarity.COMMON, mage.cards.a.AvenLiberator.class)); cards.add(new SetCardInfo("Bladewing's Thrall", 55, Rarity.UNCOMMON, mage.cards.b.BladewingsThrall.class)); cards.add(new SetCardInfo("Bladewing the Risen", 136, Rarity.RARE, mage.cards.b.BladewingTheRisen.class)); + cards.add(new SetCardInfo("Bonethorn Valesk", 82, Rarity.COMMON, mage.cards.b.BonethornValesk.class)); cards.add(new SetCardInfo("Brain Freeze", 29, Rarity.UNCOMMON, mage.cards.b.BrainFreeze.class)); cards.add(new SetCardInfo("Break Asunder", 113, Rarity.COMMON, mage.cards.b.BreakAsunder.class)); cards.add(new SetCardInfo("Cabal Conditioning", 56, Rarity.RARE, mage.cards.c.CabalConditioning.class)); From 1152458083c2ae10098e75f4f349d214ee4e13c5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 17:32:16 -0400 Subject: [PATCH 51/68] Implemented Kor Dirge --- Mage.Sets/src/mage/cards/k/KorChant.java | 2 +- Mage.Sets/src/mage/cards/k/KorDirge.java | 117 +++++++++++++++++++++++ Mage.Sets/src/mage/sets/PlanarChaos.java | 1 + 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/k/KorDirge.java diff --git a/Mage.Sets/src/mage/cards/k/KorChant.java b/Mage.Sets/src/mage/cards/k/KorChant.java index cccec9e03d..c43f7791aa 100644 --- a/Mage.Sets/src/mage/cards/k/KorChant.java +++ b/Mage.Sets/src/mage/cards/k/KorChant.java @@ -50,7 +50,7 @@ import mage.target.common.TargetCreaturePermanent; public class KorChant extends CardImpl { public KorChant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); // All damage that would be dealt this turn to target creature you control by a source of your choice is dealt to another target creature instead. this.getSpellAbility().addEffect(new KorChantEffect()); diff --git a/Mage.Sets/src/mage/cards/k/KorDirge.java b/Mage.Sets/src/mage/cards/k/KorDirge.java new file mode 100644 index 0000000000..c3020420e9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KorDirge.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.k; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.RedirectionEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherTargetPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.TargetSource; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author emerald000 + */ +public class KorDirge extends CardImpl { + + public KorDirge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); + + // All damage that would be dealt this turn to target creature you control by a source of your choice is dealt to another target creature instead. + this.getSpellAbility().addEffect(new KorDirgeEffect()); + TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); + target.setTargetTag(1); + this.getSpellAbility().addTarget(target); + + FilterCreaturePermanent filter = new FilterCreaturePermanent("another target creature"); + filter.add(new AnotherTargetPredicate(2)); + TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter); + target2.setTargetTag(2); + this.getSpellAbility().addTarget(target2); + } + + public KorDirge(final KorDirge card) { + super(card); + } + + @Override + public KorDirge copy() { + return new KorDirge(this); + } +} + +class KorDirgeEffect extends RedirectionEffect { + + protected TargetSource target = new TargetSource(); + + KorDirgeEffect() { + super(Duration.EndOfTurn); + staticText = "All damage that would be dealt this turn to target creature you control by a source of your choice is dealt to another target creature instead"; + } + + KorDirgeEffect(final KorDirgeEffect effect) { + super(effect); + this.target = effect.target; + } + + @Override + public KorDirgeEffect copy() { + return new KorDirgeEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_CREATURE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(this.getTargetPointer().getFirst(game, source)) + && event.getSourceId().equals(this.target.getFirstTarget())) { + this.redirectTarget = source.getTargets().get(1); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/PlanarChaos.java b/Mage.Sets/src/mage/sets/PlanarChaos.java index 0891962e72..6edbd651ea 100644 --- a/Mage.Sets/src/mage/sets/PlanarChaos.java +++ b/Mage.Sets/src/mage/sets/PlanarChaos.java @@ -123,6 +123,7 @@ public class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Kavu Predator", 132, Rarity.UNCOMMON, mage.cards.k.KavuPredator.class)); cards.add(new SetCardInfo("Keen Sense", 152, Rarity.UNCOMMON, mage.cards.k.KeenSense.class)); cards.add(new SetCardInfo("Keldon Marauders", 102, Rarity.COMMON, mage.cards.k.KeldonMarauders.class)); + cards.add(new SetCardInfo("Kor Dirge", 87, Rarity.UNCOMMON, mage.cards.k.KorDirge.class)); cards.add(new SetCardInfo("Lavacore Elemental", 103, Rarity.UNCOMMON, mage.cards.l.LavacoreElemental.class)); cards.add(new SetCardInfo("Life and Limb", 133, Rarity.RARE, mage.cards.l.LifeAndLimb.class)); cards.add(new SetCardInfo("Magus of the Arena", 104, Rarity.RARE, mage.cards.m.MagusOfTheArena.class)); From b91342f0c63bc2c8792bbc63251a39adc35f91e6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 17:37:31 -0400 Subject: [PATCH 52/68] Implemented Veiling Oddity --- Mage.Sets/src/mage/cards/v/VeilingOddity.java | 106 ++++++++++++++++++ Mage.Sets/src/mage/sets/PlanarChaos.java | 1 + 2 files changed, 107 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VeilingOddity.java diff --git a/Mage.Sets/src/mage/cards/v/VeilingOddity.java b/Mage.Sets/src/mage/cards/v/VeilingOddity.java new file mode 100644 index 0000000000..8ababf2561 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeilingOddity.java @@ -0,0 +1,106 @@ +/* + * 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.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantBeBlockedAllEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author TheElk801 + */ +public class VeilingOddity extends CardImpl { + + public VeilingOddity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Suspend 4-{1}{U} + this.addAbility(new SuspendAbility(4, new ManaCostsImpl("{1}{U}"), this)); + + // When the last time counter is removed from Veiling Oddity while it's exiled, creatures are unblockable this turn. + this.addAbility(new VeilingOddityTriggeredAbility()); + } + + public VeilingOddity(final VeilingOddity card) { + super(card); + } + + @Override + public VeilingOddity copy() { + return new VeilingOddity(this); + } +} + +class VeilingOddityTriggeredAbility extends TriggeredAbilityImpl { + + public VeilingOddityTriggeredAbility() { + super(Zone.EXILED, new CantBeBlockedAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES, Duration.EndOfTurn), false); + } + + public VeilingOddityTriggeredAbility(final VeilingOddityTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COUNTER_REMOVED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return (event.getTargetId().equals(this.getSourceId()) && game.getCard(event.getTargetId()).getCounters(game).getCount(CounterType.TIME) == 0); + } + + @Override + public String getRule() { + return "When the last time counter is removed from {this} while it's exiled, " + super.getRule(); + } + + @Override + public VeilingOddityTriggeredAbility copy() { + return new VeilingOddityTriggeredAbility(this); + } +} diff --git a/Mage.Sets/src/mage/sets/PlanarChaos.java b/Mage.Sets/src/mage/sets/PlanarChaos.java index 6edbd651ea..a3e52b2ad7 100644 --- a/Mage.Sets/src/mage/sets/PlanarChaos.java +++ b/Mage.Sets/src/mage/sets/PlanarChaos.java @@ -204,6 +204,7 @@ public class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", 165, Rarity.RARE, mage.cards.u.UrborgTombOfYawgmoth.class)); cards.add(new SetCardInfo("Utopia Vow", 142, Rarity.COMMON, mage.cards.u.UtopiaVow.class)); cards.add(new SetCardInfo("Vampiric Link", 92, Rarity.COMMON, mage.cards.v.VampiricLink.class)); + cards.add(new SetCardInfo("Veiling Oddity", 51, Rarity.COMMON, mage.cards.v.VeilingOddity.class)); cards.add(new SetCardInfo("Venarian Glimmer", 52, Rarity.UNCOMMON, mage.cards.v.VenarianGlimmer.class)); cards.add(new SetCardInfo("Vitaspore Thallid", 143, Rarity.COMMON, mage.cards.v.VitasporeThallid.class)); cards.add(new SetCardInfo("Voidstone Gargoyle", 21, Rarity.RARE, mage.cards.v.VoidstoneGargoyle.class)); From b320d1d0f043c04779bacb4c508c9313ebd109da Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 18:02:10 -0400 Subject: [PATCH 53/68] Implemented Forgotten Harvest --- .../src/mage/cards/f/ForgottenHarvest.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/Prophecy.java | 1 + .../costs/common/ExileFromGraveCost.java | 9 ++- 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/ForgottenHarvest.java diff --git a/Mage.Sets/src/mage/cards/f/ForgottenHarvest.java b/Mage.Sets/src/mage/cards/f/ForgottenHarvest.java new file mode 100644 index 0000000000..c698fea613 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/ForgottenHarvest.java @@ -0,0 +1,74 @@ +/* + * 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.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterLandCard; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ForgottenHarvest extends CardImpl { + + public ForgottenHarvest(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + + // At the beginning of your upkeep, you may exile a land card from your graveyard. If you do, put a +1/+1 counter on target creature. + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new DoIfCostPaid( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()), + new ExileFromGraveCost(new TargetCardInYourGraveyard(new FilterLandCard("land card from your graveyard"))) + ), + TargetController.YOU, false + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public ForgottenHarvest(final ForgottenHarvest card) { + super(card); + } + + @Override + public ForgottenHarvest copy() { + return new ForgottenHarvest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 2ee3996d7d..03b140387b 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -90,6 +90,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Flameshot", 90, Rarity.UNCOMMON, mage.cards.f.Flameshot.class)); cards.add(new SetCardInfo("Flowering Field", 9, Rarity.UNCOMMON, mage.cards.f.FloweringField.class)); cards.add(new SetCardInfo("Foil", 34, Rarity.UNCOMMON, mage.cards.f.Foil.class)); + cards.add(new SetCardInfo("Forgotten Harvest", 114, Rarity.RARE, mage.cards.f.ForgottenHarvest.class)); cards.add(new SetCardInfo("Greel's Caress", 67, Rarity.COMMON, mage.cards.g.GreelsCaress.class)); cards.add(new SetCardInfo("Greel, Mind Raker", 66, Rarity.RARE, mage.cards.g.GreelMindRaker.class)); cards.add(new SetCardInfo("Gulf Squid", 35, Rarity.COMMON, mage.cards.g.GulfSquid.class)); diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java index 58806243da..c7adda1c79 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromGraveCost.java @@ -53,12 +53,13 @@ public class ExileFromGraveCost extends CostImpl { private final List exiledCards = new ArrayList<>(); public ExileFromGraveCost(TargetCardInYourGraveyard target) { + target.setNotTarget(true); this.addTarget(target); if (target.getMaxNumberOfTargets() > 1) { this.text = "Exile " + (target.getNumberOfTargets() == 1 && target.getMaxNumberOfTargets() == Integer.MAX_VALUE ? "one or more" - : ((target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to " : "")) - + CardUtil.numberToText(target.getMaxNumberOfTargets())) + : ((target.getNumberOfTargets() < target.getMaxNumberOfTargets() ? "up to " : "")) + + CardUtil.numberToText(target.getMaxNumberOfTargets())) + ' ' + target.getTargetName(); } else { this.text = "Exile " + target.getTargetName(); @@ -69,11 +70,13 @@ public class ExileFromGraveCost extends CostImpl { } public ExileFromGraveCost(TargetCardInYourGraveyard target, String text) { - this(target); + target.setNotTarget(true); + this.addTarget(target); this.text = text; } public ExileFromGraveCost(TargetCardInASingleGraveyard target) { + target.setNotTarget(true); this.addTarget(target); this.text = "Exile " + target.getTargetName(); } From 7867fbdf28e2332a42d6848146af3cb684fb5123 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 18:16:52 -0400 Subject: [PATCH 54/68] Implemented Unified Strike --- Mage.Sets/src/mage/cards/u/UnifiedStrike.java | 107 ++++++++++++++++++ Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 108 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/u/UnifiedStrike.java diff --git a/Mage.Sets/src/mage/cards/u/UnifiedStrike.java b/Mage.Sets/src/mage/cards/u/UnifiedStrike.java new file mode 100644 index 0000000000..87b42ae662 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnifiedStrike.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.u; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetAttackingCreature; + +/** + * + * @author TheElk801 + */ +public class UnifiedStrike extends CardImpl { + + public UnifiedStrike(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Exile target attacking creature if its power is less than or equal to the number of Soldiers on the battlefield. + this.getSpellAbility().addEffect(new UnifiedStrikeEffect()); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public UnifiedStrike(final UnifiedStrike card) { + super(card); + } + + @Override + public UnifiedStrike copy() { + return new UnifiedStrike(this); + } +} + +class UnifiedStrikeEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent(); + + static { + filter.add(new SubtypePredicate(SubType.SOLDIER)); + } + + UnifiedStrikeEffect() { + super(Outcome.Benefit); + this.staticText = ""; + } + + UnifiedStrikeEffect(final UnifiedStrikeEffect effect) { + super(effect); + } + + @Override + public UnifiedStrikeEffect copy() { + return new UnifiedStrikeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(source.getFirstTarget()); + Player player = game.getPlayer(source.getControllerId()); + if (creature == null || player == null) { + return false; + } + int soldierCount = game.getBattlefield() + .getActivePermanents( + filter, + source.getControllerId(), + source.getSourceId(), + game + ).size(); + return creature.getPower().getValue() <= soldierCount; + } +} diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index 5999dfc361..ae21f921fc 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -316,6 +316,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("True Believer", 57, Rarity.RARE, mage.cards.t.TrueBeliever.class)); cards.add(new SetCardInfo("Undead Gladiator", 178, Rarity.RARE, mage.cards.u.UndeadGladiator.class)); cards.add(new SetCardInfo("Unholy Grotto", 327, Rarity.RARE, mage.cards.u.UnholyGrotto.class)); + cards.add(new SetCardInfo("Unified Strike", 58, Rarity.COMMON, mage.cards.u.UnifiedStrike.class)); cards.add(new SetCardInfo("Venomspout Brackus", 295, Rarity.UNCOMMON, mage.cards.v.VenomspoutBrackus.class)); cards.add(new SetCardInfo("Visara the Dreadful", 179, Rarity.RARE, mage.cards.v.VisaraTheDreadful.class)); cards.add(new SetCardInfo("Vitality Charm", 296, Rarity.COMMON, mage.cards.v.VitalityCharm.class)); From debcfcd47c12e27707b1b5d87cf38ef704de2cd8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 19:55:47 -0400 Subject: [PATCH 55/68] Implemented Interdict --- Mage.Sets/src/mage/cards/i/Interdict.java | 159 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Tempest.java | 1 + 2 files changed, 160 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/Interdict.java diff --git a/Mage.Sets/src/mage/cards/i/Interdict.java b/Mage.Sets/src/mage/cards/i/Interdict.java new file mode 100644 index 0000000000..5fcc1c5244 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/Interdict.java @@ -0,0 +1,159 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterStackObject; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.target.common.TargetActivatedOrTriggeredAbility; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class Interdict extends CardImpl { + + private static final FilterStackObject filter = new FilterStackObject("activated ability from an artifact, creature, enchantment, or land"); + + static { + filter.add(new InterdictPredicate()); + } + + public Interdict(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Counter target activated ability from an artifact, creature, enchantment, or land. That permanent's activated abilities can't be activated this turn. + this.getSpellAbility().addEffect(new InterdictCounterEffect()); + this.getSpellAbility().addTarget(new TargetActivatedOrTriggeredAbility(filter)); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); + } + + public Interdict(final Interdict card) { + super(card); + } + + @Override + public Interdict copy() { + return new Interdict(this); + } +} + +class InterdictPredicate implements Predicate { + + public InterdictPredicate() { + } + + @Override + public boolean apply(Ability input, Game game) { + if (input instanceof StackAbility && input.getAbilityType() == AbilityType.ACTIVATED) { + Permanent sourceObject = game.getPermanentOrLKIBattlefield(input.getSourceId()); + if (sourceObject != null) { + return (sourceObject.isArtifact() + || sourceObject.isEnchantment() + || sourceObject.isCreature() + || sourceObject.isLand()); + } + } + return false; + } +} + +class InterdictCounterEffect extends OneShotEffect { + + public InterdictCounterEffect() { + super(Outcome.Detriment); + staticText = "Counter target activated ability from an artifact, creature, enchantment, or land. That permanent's activated abilities can't be activated this turn."; + } + + public InterdictCounterEffect(final InterdictCounterEffect effect) { + super(effect); + } + + @Override + public InterdictCounterEffect copy() { + return new InterdictCounterEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget()); + if (stackObject != null && game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) { + InterdictCantActivateEffect effect = new InterdictCantActivateEffect(); + effect.setTargetPointer(new FixedTarget(stackObject.getSourceId())); + game.getContinuousEffects().addEffect(effect, source); + return true; + } + return false; + } + +} + +class InterdictCantActivateEffect extends RestrictionEffect { + + public InterdictCantActivateEffect() { + super(Duration.EndOfTurn); + staticText = "That permanent's activated abilities can't be activated this turn"; + } + + public InterdictCantActivateEffect(final InterdictCantActivateEffect effect) { + super(effect); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return getTargetPointer().getFirst(game, source).equals(permanent.getId()); + } + + @Override + public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game) { + return false; + } + + @Override + public InterdictCantActivateEffect copy() { + return new InterdictCantActivateEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/Tempest.java b/Mage.Sets/src/mage/sets/Tempest.java index 4bec44d37b..ddf3186ae4 100644 --- a/Mage.Sets/src/mage/sets/Tempest.java +++ b/Mage.Sets/src/mage/sets/Tempest.java @@ -156,6 +156,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Humility", 236, Rarity.RARE, mage.cards.h.Humility.class)); cards.add(new SetCardInfo("Imps' Taunt", 32, Rarity.UNCOMMON, mage.cards.i.ImpsTaunt.class)); cards.add(new SetCardInfo("Insight", 68, Rarity.UNCOMMON, mage.cards.i.Insight.class)); + cards.add(new SetCardInfo("Interdict", 69, Rarity.UNCOMMON, mage.cards.i.Interdict.class)); cards.add(new SetCardInfo("Intuition", 70, Rarity.RARE, mage.cards.i.Intuition.class)); cards.add(new SetCardInfo("Invulnerability", 237, Rarity.UNCOMMON, mage.cards.i.Invulnerability.class)); cards.add(new SetCardInfo("Island", 313, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); From 0ea78d21ef6af761eb0a26d70ea23258d5e88bae Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 20:12:49 -0400 Subject: [PATCH 56/68] Implemented Spheres from Odyssey --- Mage.Sets/src/mage/cards/s/SphereOfDuty.java | 60 +++++++++++++++ Mage.Sets/src/mage/cards/s/SphereOfGrace.java | 60 +++++++++++++++ Mage.Sets/src/mage/cards/s/SphereOfLaw.java | 60 +++++++++++++++ .../src/mage/cards/s/SphereOfReason.java | 60 +++++++++++++++ Mage.Sets/src/mage/cards/s/SphereOfTruth.java | 60 +++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 5 ++ .../common/PreventDamageByColorEffect.java | 77 +++++++++++++++++++ 7 files changed, 382 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfDuty.java create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfGrace.java create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfLaw.java create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfReason.java create mode 100644 Mage.Sets/src/mage/cards/s/SphereOfTruth.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/PreventDamageByColorEffect.java diff --git a/Mage.Sets/src/mage/cards/s/SphereOfDuty.java b/Mage.Sets/src/mage/cards/s/SphereOfDuty.java new file mode 100644 index 0000000000..22df3290c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfDuty.java @@ -0,0 +1,60 @@ +/* + * 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.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventDamageByColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SphereOfDuty extends CardImpl { + + public SphereOfDuty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If a green source would deal damage to you, prevent 2 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageByColorEffect(ObjectColor.GREEN, 2))); + } + + public SphereOfDuty(final SphereOfDuty card) { + super(card); + } + + @Override + public SphereOfDuty copy() { + return new SphereOfDuty(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SphereOfGrace.java b/Mage.Sets/src/mage/cards/s/SphereOfGrace.java new file mode 100644 index 0000000000..c80f84d066 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfGrace.java @@ -0,0 +1,60 @@ +/* + * 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.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventDamageByColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SphereOfGrace extends CardImpl { + + public SphereOfGrace(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If a black source would deal damage to you, prevent 2 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageByColorEffect(ObjectColor.BLACK, 2))); + } + + public SphereOfGrace(final SphereOfGrace card) { + super(card); + } + + @Override + public SphereOfGrace copy() { + return new SphereOfGrace(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SphereOfLaw.java b/Mage.Sets/src/mage/cards/s/SphereOfLaw.java new file mode 100644 index 0000000000..66cae254c8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfLaw.java @@ -0,0 +1,60 @@ +/* + * 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.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventDamageByColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SphereOfLaw extends CardImpl { + + public SphereOfLaw(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If a red source would deal damage to you, prevent 2 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageByColorEffect(ObjectColor.RED, 2))); + } + + public SphereOfLaw(final SphereOfLaw card) { + super(card); + } + + @Override + public SphereOfLaw copy() { + return new SphereOfLaw(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SphereOfReason.java b/Mage.Sets/src/mage/cards/s/SphereOfReason.java new file mode 100644 index 0000000000..c7c7746fa7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfReason.java @@ -0,0 +1,60 @@ +/* + * 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.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventDamageByColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SphereOfReason extends CardImpl { + + public SphereOfReason(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If a blue source would deal damage to you, prevent 2 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageByColorEffect(ObjectColor.BLUE, 2))); + } + + public SphereOfReason(final SphereOfReason card) { + super(card); + } + + @Override + public SphereOfReason copy() { + return new SphereOfReason(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SphereOfTruth.java b/Mage.Sets/src/mage/cards/s/SphereOfTruth.java new file mode 100644 index 0000000000..5260505d05 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphereOfTruth.java @@ -0,0 +1,60 @@ +/* + * 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.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventDamageByColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SphereOfTruth extends CardImpl { + + public SphereOfTruth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // If a white source would deal damage to you, prevent 2 of that damage. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageByColorEffect(ObjectColor.WHITE, 2))); + } + + public SphereOfTruth(final SphereOfTruth card) { + super(card); + } + + @Override + public SphereOfTruth copy() { + return new SphereOfTruth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index 77297a0864..b7dfb3216c 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -319,6 +319,11 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Soulcatcher", 47, Rarity.UNCOMMON, mage.cards.s.Soulcatcher.class)); cards.add(new SetCardInfo("Spark Mage", 222, Rarity.UNCOMMON, mage.cards.s.SparkMage.class)); cards.add(new SetCardInfo("Spellbane Centaur", 271, Rarity.RARE, mage.cards.s.SpellbaneCentaur.class)); + cards.add(new SetCardInfo("Sphere of Duty", 48, Rarity.UNCOMMON, mage.cards.s.SphereOfDuty.class)); + cards.add(new SetCardInfo("Sphere of Grace", 49, Rarity.UNCOMMON, mage.cards.s.SphereOfGrace.class)); + cards.add(new SetCardInfo("Sphere of Law", 50, Rarity.UNCOMMON, mage.cards.s.SphereOfLaw.class)); + cards.add(new SetCardInfo("Sphere of Reason", 51, Rarity.UNCOMMON, mage.cards.s.SphereOfReason.class)); + cards.add(new SetCardInfo("Sphere of Truth", 52, Rarity.UNCOMMON, mage.cards.s.SphereOfTruth.class)); cards.add(new SetCardInfo("Spiritualize", 53, Rarity.UNCOMMON, mage.cards.s.Spiritualize.class)); cards.add(new SetCardInfo("Springing Tiger", 272, Rarity.COMMON, mage.cards.s.SpringingTiger.class)); cards.add(new SetCardInfo("Squirrel Mob", 273, Rarity.RARE, mage.cards.s.SquirrelMob.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageByColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageByColorEffect.java new file mode 100644 index 0000000000..c70887bc4f --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageByColorEffect.java @@ -0,0 +1,77 @@ +/* + * 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.abilities.effects.common; + +import mage.MageObject; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.PreventionEffectImpl; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author LevelX2 + */ +public class PreventDamageByColorEffect extends PreventionEffectImpl { + + private final ObjectColor color; + + public PreventDamageByColorEffect(ObjectColor color, int amount) { + super(Duration.WhileOnBattlefield, amount, false, false); + this.color = color; + this.staticText = "If a " + color.getDescription() + " source would deal damage to you, prevent " + amount + " of that damage"; + } + + public PreventDamageByColorEffect(PreventDamageByColorEffect effect) { + super(effect); + this.color = effect.color; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(source.getControllerId())) { + MageObject sourceObject = game.getObject(event.getSourceId()); + if (sourceObject != null && sourceObject.getColor(game).contains(color)) { + return super.applies(event, source, game); + } + } + return false; + } + + @Override + public PreventDamageByColorEffect copy() { + return new PreventDamageByColorEffect(this); + } +} From 54ddb594f8dd21075cd4e1fc0188a2902aa5ae76 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 20:20:34 -0400 Subject: [PATCH 57/68] Implemented Twigwalker --- .../src/mage/cards/m/MischiefAndMayhem.java | 7 +- Mage.Sets/src/mage/cards/t/Twigwalker.java | 73 +++++++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 1 + 3 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/Twigwalker.java diff --git a/Mage.Sets/src/mage/cards/m/MischiefAndMayhem.java b/Mage.Sets/src/mage/cards/m/MischiefAndMayhem.java index e6c2c1da4d..bdbc676c64 100644 --- a/Mage.Sets/src/mage/cards/m/MischiefAndMayhem.java +++ b/Mage.Sets/src/mage/cards/m/MischiefAndMayhem.java @@ -43,12 +43,11 @@ import mage.target.common.TargetCreaturePermanent; public class MischiefAndMayhem extends CardImpl { public MischiefAndMayhem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}"); // Up to two target creatures each get +4/+4 until end of turn. - this.getSpellAbility().addEffect(new BoostTargetEffect(4,4, Duration.EndOfTurn)); - this.getSpellAbility().addTarget(new TargetCreaturePermanent(0,2, new FilterCreaturePermanent("creatures each"), false)); + this.getSpellAbility().addEffect(new BoostTargetEffect(4, 4, Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2, new FilterCreaturePermanent("creatures each"), false)); } public MischiefAndMayhem(final MischiefAndMayhem card) { diff --git a/Mage.Sets/src/mage/cards/t/Twigwalker.java b/Mage.Sets/src/mage/cards/t/Twigwalker.java new file mode 100644 index 0000000000..946821a20e --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/Twigwalker.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class Twigwalker extends CardImpl { + + public Twigwalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.INSECT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}{G}, Sacrifice Twigwalker: Two target creatures each get +2/+2 until end of turn. + Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{1}{G}")); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent(2, 2, new FilterCreaturePermanent("creatures each"), false)); + this.addAbility(ability); + } + + public Twigwalker(final Twigwalker card) { + super(card); + } + + @Override + public Twigwalker copy() { + return new Twigwalker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index b7dfb3216c..e0f55127b5 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -359,6 +359,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Traumatize", 110, Rarity.RARE, mage.cards.t.Traumatize.class)); cards.add(new SetCardInfo("Treetop Sentinel", 111, Rarity.UNCOMMON, mage.cards.t.TreetopSentinel.class)); cards.add(new SetCardInfo("Tremble", 225, Rarity.COMMON, mage.cards.t.Tremble.class)); + cards.add(new SetCardInfo("Twigwalker", 279, Rarity.UNCOMMON, mage.cards.t.Twigwalker.class)); cards.add(new SetCardInfo("Unifying Theory", 112, Rarity.RARE, mage.cards.u.UnifyingTheory.class)); cards.add(new SetCardInfo("Upheaval", 113, Rarity.RARE, mage.cards.u.Upheaval.class)); cards.add(new SetCardInfo("Vampiric Dragon", 296, Rarity.RARE, mage.cards.v.VampiricDragon.class)); From 9e574d9ab4199703b397c4ab0ad262a4225ae71f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 20:30:54 -0400 Subject: [PATCH 58/68] Implemented Junk Golem --- Mage.Sets/src/mage/cards/j/JunkGolem.java | 85 +++++++++++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JunkGolem.java diff --git a/Mage.Sets/src/mage/cards/j/JunkGolem.java b/Mage.Sets/src/mage/cards/j/JunkGolem.java new file mode 100644 index 0000000000..73bb7f1c6d --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JunkGolem.java @@ -0,0 +1,85 @@ +/* + * 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.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class JunkGolem extends CardImpl { + + public JunkGolem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add(SubType.GOLEM); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Junk Golem enters the battlefield with three +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it")); + + // At the beginning of your upkeep, sacrifice Junk Golem unless you remove a +1/+1 counter from it. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new SacrificeSourceUnlessPaysEffect( + new RemoveCountersSourceCost(CounterType.P1P1.createInstance()) + ), TargetController.YOU, false + )); + + // {1}, Discard a card: Put a +1/+1 counter on Junk Golem. + Ability ability = new SimpleActivatedAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl("{1}")); + ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + } + + public JunkGolem(final JunkGolem card) { + super(card); + } + + @Override + public JunkGolem copy() { + return new JunkGolem(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index e0f55127b5..ba6d7e05f6 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -194,6 +194,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ivy Elemental", 245, Rarity.RARE, mage.cards.i.IvyElemental.class)); + cards.add(new SetCardInfo("Junk Golem", 300, Rarity.RARE, mage.cards.j.JunkGolem.class)); cards.add(new SetCardInfo("Kamahl, Pit Fighter", 198, Rarity.RARE, mage.cards.k.KamahlPitFighter.class)); cards.add(new SetCardInfo("Kamahl's Desire", 199, Rarity.COMMON, mage.cards.k.KamahlsDesire.class)); cards.add(new SetCardInfo("Karmic Justice", 26, Rarity.RARE, mage.cards.k.KarmicJustice.class)); From 0464bb7c4fe7c31d472c9c1f76a9492ae907c24d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 20:38:59 -0400 Subject: [PATCH 59/68] Implemented Otarian Juggernaut --- Mage.Sets/src/mage/cards/j/Juggernaut.java | 5 +- .../src/mage/cards/o/OtarianJuggernaut.java | 96 +++++++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 1 + 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/o/OtarianJuggernaut.java diff --git a/Mage.Sets/src/mage/cards/j/Juggernaut.java b/Mage.Sets/src/mage/cards/j/Juggernaut.java index de9b218486..9f40456495 100644 --- a/Mage.Sets/src/mage/cards/j/Juggernaut.java +++ b/Mage.Sets/src/mage/cards/j/Juggernaut.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.j; import java.util.UUID; @@ -48,18 +47,20 @@ import mage.filter.predicate.mageobject.SubtypePredicate; public class Juggernaut extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Walls"); + static { filter.add(new SubtypePredicate(SubType.WALL)); } public Juggernaut(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); this.subtype.add(SubType.JUGGERNAUT); this.power = new MageInt(5); this.toughness = new MageInt(3); // Juggernaut attacks each turn if able. this.addAbility(new AttacksEachCombatStaticAbility()); + // Juggernaut can't be blocked by Walls. this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); } diff --git a/Mage.Sets/src/mage/cards/o/OtarianJuggernaut.java b/Mage.Sets/src/mage/cards/o/OtarianJuggernaut.java new file mode 100644 index 0000000000..ac83986542 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OtarianJuggernaut.java @@ -0,0 +1,96 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.combat.AttacksIfAbleSourceEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class OtarianJuggernaut extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Walls"); + + static { + filter.add(new SubtypePredicate(SubType.WALL)); + } + + public OtarianJuggernaut(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add(SubType.JUGGERNAUT); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Otarian Juggernaut can't be blocked by Walls. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + + // Threshold - As long as seven or more cards are in your graveyard, Otarian Juggernaut gets +3/+0 and attacks each combat if able. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(3, 0, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +3/+0")); + Effect effect = new ConditionalContinuousEffect( + new AttacksIfAbleSourceEffect(Duration.WhileOnBattlefield, true), + new CardsInControllerGraveCondition(7), + "and attacks each combat if able" + ); + ability.addEffect(effect); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public OtarianJuggernaut(final OtarianJuggernaut card) { + super(card); + } + + @Override + public OtarianJuggernaut copy() { + return new OtarianJuggernaut(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index ba6d7e05f6..046a90917c 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -251,6 +251,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Nomad Stadium", 322, Rarity.UNCOMMON, mage.cards.n.NomadStadium.class)); cards.add(new SetCardInfo("Nut Collector", 259, Rarity.RARE, mage.cards.n.NutCollector.class)); cards.add(new SetCardInfo("Obstinate Familiar", 210, Rarity.RARE, mage.cards.o.ObstinateFamiliar.class)); + cards.add(new SetCardInfo("Otarian Juggernaut", 305, Rarity.RARE, mage.cards.o.OtarianJuggernaut.class)); cards.add(new SetCardInfo("Overeager Apprentice", 154, Rarity.COMMON, mage.cards.o.OvereagerApprentice.class)); cards.add(new SetCardInfo("Overrun", 260, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); cards.add(new SetCardInfo("Pardic Firecat", 211, Rarity.COMMON, mage.cards.p.PardicFirecat.class)); From 7c88e7b4ce2d8919777d493729da709f11a229ad Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 21:17:42 -0400 Subject: [PATCH 60/68] Implemented Burning Palm Efreet --- .../src/mage/cards/b/BurningPalmEfreet.java | 83 +++++++++++++++++++ Mage.Sets/src/mage/sets/Mirage.java | 1 + 2 files changed, 84 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BurningPalmEfreet.java diff --git a/Mage.Sets/src/mage/cards/b/BurningPalmEfreet.java b/Mage.Sets/src/mage/cards/b/BurningPalmEfreet.java new file mode 100644 index 0000000000..1208ee6e9e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BurningPalmEfreet.java @@ -0,0 +1,83 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class BurningPalmEfreet extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public BurningPalmEfreet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.EFREET); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}{R}{R}: Burning Palm Efreet deals 2 damage to target creature with flying and that creature loses flying until end of turn. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new ManaCostsImpl("{1}{R}{R}")); + ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn) + .setText("and that creature loses flying until end of turn") + ); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public BurningPalmEfreet(final BurningPalmEfreet card) { + super(card); + } + + @Override + public BurningPalmEfreet copy() { + return new BurningPalmEfreet(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index d9c19913d7..5305eca568 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -79,6 +79,7 @@ public class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Boomerang", 56, Rarity.COMMON, mage.cards.b.Boomerang.class)); cards.add(new SetCardInfo("Breathstealer", 7, Rarity.COMMON, mage.cards.b.Breathstealer.class)); cards.add(new SetCardInfo("Brushwagg", 106, Rarity.RARE, mage.cards.b.Brushwagg.class)); + cards.add(new SetCardInfo("Burning Palm Efreet", 161, Rarity.UNCOMMON, mage.cards.b.BurningPalmEfreet.class)); cards.add(new SetCardInfo("Burning Shield Askari", 162, Rarity.COMMON, mage.cards.b.BurningShieldAskari.class)); cards.add(new SetCardInfo("Cadaverous Bloom", 318, Rarity.RARE, mage.cards.c.CadaverousBloom.class)); cards.add(new SetCardInfo("Cadaverous Knight", 8, Rarity.COMMON, mage.cards.c.CadaverousKnight.class)); From 3b7f3e791746589e8ccfc156a0cf14c7e0c0b42c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 21:26:02 -0400 Subject: [PATCH 61/68] Implemented Divine Retribution --- .../src/mage/cards/d/DivineRetribution.java | 64 +++++++++++++++++++ Mage.Sets/src/mage/sets/Mirage.java | 1 + 2 files changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DivineRetribution.java diff --git a/Mage.Sets/src/mage/cards/d/DivineRetribution.java b/Mage.Sets/src/mage/cards/d/DivineRetribution.java new file mode 100644 index 0000000000..c73e8933b2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DivineRetribution.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.d; + +import java.util.UUID; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterAttackingCreature; +import mage.target.common.TargetAttackingCreature; + +/** + * + * @author TheElk801 + */ +public class DivineRetribution extends CardImpl { + + public DivineRetribution(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Divine Retribution deals damage to target attacking creature equal to the number of attacking creatures. + this.getSpellAbility().addEffect( + new DamageTargetEffect(new PermanentsOnBattlefieldCount(new FilterAttackingCreature())) + .setText("{this} deals damage to target attacking creature equal to the number of attacking creatures.") + ); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + } + + public DivineRetribution(final DivineRetribution card) { + super(card); + } + + @Override + public DivineRetribution copy() { + return new DivineRetribution(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index 5305eca568..c0a12b0a05 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -110,6 +110,7 @@ public class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Disenchant", 214, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Dissipate", 61, Rarity.UNCOMMON, mage.cards.d.Dissipate.class)); cards.add(new SetCardInfo("Divine Offering", 215, Rarity.COMMON, mage.cards.d.DivineOffering.class)); + cards.add(new SetCardInfo("Divine Retribution", 216, Rarity.RARE, mage.cards.d.DivineRetribution.class)); cards.add(new SetCardInfo("Drain Life", 16, Rarity.COMMON, mage.cards.d.DrainLife.class)); cards.add(new SetCardInfo("Dread Specter", 17, Rarity.UNCOMMON, mage.cards.d.DreadSpecter.class)); cards.add(new SetCardInfo("Dream Cache", 62, Rarity.COMMON, mage.cards.d.DreamCache.class)); From d1cd7bdac47ee789b86243e024b5905143741c62 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 21:34:38 -0400 Subject: [PATCH 62/68] Implemented Leering Gargoyle --- .../src/mage/cards/l/LeeringGargoyle.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Mirage.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LeeringGargoyle.java diff --git a/Mage.Sets/src/mage/cards/l/LeeringGargoyle.java b/Mage.Sets/src/mage/cards/l/LeeringGargoyle.java new file mode 100644 index 0000000000..cd481a8697 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LeeringGargoyle.java @@ -0,0 +1,81 @@ +/* + * 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.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author TheElk801 + */ +public class LeeringGargoyle extends CardImpl { + + public LeeringGargoyle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); + + this.subtype.add(SubType.GARGOYLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {tap}: Leering Gargoyle gets -2/+2 and loses flying until end of turn. + Ability ability = new SimpleActivatedAbility( + new BoostSourceEffect(-2, 2, Duration.EndOfTurn) + .setText("{this} gets -2/+2"), + new TapSourceCost() + ); + ability.addEffect( + new LoseAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn) + .setText("and loses flying until end of turn") + ); + this.addAbility(ability); + } + + public LeeringGargoyle(final LeeringGargoyle card) { + super(card); + } + + @Override + public LeeringGargoyle copy() { + return new LeeringGargoyle(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index c0a12b0a05..2100e30fab 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -193,6 +193,7 @@ public class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Kukemssa Pirates", 71, Rarity.RARE, mage.cards.k.KukemssaPirates.class)); cards.add(new SetCardInfo("Kukemssa Serpent", 72, Rarity.COMMON, mage.cards.k.KukemssaSerpent.class)); cards.add(new SetCardInfo("Lead Golem", 271, Rarity.UNCOMMON, mage.cards.l.LeadGolem.class)); + cards.add(new SetCardInfo("Leering Gargoyle", 331, Rarity.RARE, mage.cards.l.LeeringGargoyle.class)); cards.add(new SetCardInfo("Lightning Reflexes", 186, Rarity.COMMON, mage.cards.l.LightningReflexes.class)); cards.add(new SetCardInfo("Lion's Eye Diamond", 272, Rarity.RARE, mage.cards.l.LionsEyeDiamond.class)); cards.add(new SetCardInfo("Locust Swarm", 124, Rarity.UNCOMMON, mage.cards.l.LocustSwarm.class)); From 17b7de4e87979cf9c9d76f1c5309254ba6a7a07b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 5 Oct 2017 22:02:41 -0400 Subject: [PATCH 63/68] Implemented Drinker of Sorrow --- .../src/mage/cards/d/DrinkerOfSorrow.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Legions.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DrinkerOfSorrow.java diff --git a/Mage.Sets/src/mage/cards/d/DrinkerOfSorrow.java b/Mage.Sets/src/mage/cards/d/DrinkerOfSorrow.java new file mode 100644 index 0000000000..65f1933c1e --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DrinkerOfSorrow.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.DealsCombatDamageTriggeredAbility; +import mage.abilities.effects.common.SacrificeEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; + +/** + * + * @author TheElk801 + */ +public class DrinkerOfSorrow extends CardImpl { + + public DrinkerOfSorrow(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.HORROR); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Drinker of Sorrow can't block. + this.addAbility(new CantBlockAbility()); + + // Whenever Drinker of Sorrow deals combat damage, sacrifice a permanent. + this.addAbility(new DealsCombatDamageTriggeredAbility(new SacrificeEffect(new FilterPermanent(), 1, ""), false)); + } + + public DrinkerOfSorrow(final DrinkerOfSorrow card) { + super(card); + } + + @Override + public DrinkerOfSorrow copy() { + return new DrinkerOfSorrow(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index 8d8368aca7..2622f22cb0 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -90,6 +90,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Deftblade Elite", 12, Rarity.COMMON, mage.cards.d.DeftbladeElite.class)); cards.add(new SetCardInfo("Dermoplasm", 35, Rarity.RARE, mage.cards.d.Dermoplasm.class)); cards.add(new SetCardInfo("Dreamborn Muse", 36, Rarity.RARE, mage.cards.d.DreambornMuse.class)); + cards.add(new SetCardInfo("Drinker of Sorrow", 66, Rarity.RARE, mage.cards.d.DrinkerOfSorrow.class)); cards.add(new SetCardInfo("Dripping Dead", 67, Rarity.COMMON, mage.cards.d.DrippingDead.class)); cards.add(new SetCardInfo("Earthblighter", 68, Rarity.UNCOMMON, mage.cards.e.Earthblighter.class)); cards.add(new SetCardInfo("Echo Tracer", 37, Rarity.COMMON, mage.cards.e.EchoTracer.class)); From 3baabe2534f8a3637feb290475a5ad400f226dcd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 16:55:46 -0400 Subject: [PATCH 64/68] some text fixes --- Mage.Sets/src/mage/cards/b/Bequeathal.java | 4 ++-- Mage.Sets/src/mage/cards/c/ChillHaunting.java | 2 +- Mage.Sets/src/mage/cards/d/DecreeOfSilence.java | 12 ++++++------ Mage.Sets/src/mage/cards/e/EntropicSpecter.java | 4 ++-- Mage.Sets/src/mage/cards/m/MercurialKite.java | 2 +- Mage.Sets/src/mage/cards/m/MischievousQuanar.java | 8 ++++---- Mage.Sets/src/mage/cards/o/OneWithNature.java | 9 +++++---- Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java | 2 +- Mage.Sets/src/mage/cards/r/ReapingTheGraves.java | 5 ++--- Mage.Sets/src/mage/cards/r/ReapingTheRewards.java | 6 +++--- Mage.Sets/src/mage/cards/r/RecklessOgre.java | 4 ++-- Mage.Sets/src/mage/cards/r/RewardTheFaithful.java | 5 +++-- Mage.Sets/src/mage/cards/s/ScaldingSalamander.java | 2 +- Mage.Sets/src/mage/cards/s/SpikeCannibal.java | 4 ++-- Mage.Sets/src/mage/cards/s/SpikeRogue.java | 8 ++++---- Mage.Sets/src/mage/cards/s/SpikeWeaver.java | 8 ++++---- Mage.Sets/src/mage/cards/t/TorrentOfFire.java | 6 ++++-- Mage.Sets/src/mage/cards/v/VengefulDead.java | 8 ++++---- Mage.Sets/src/mage/cards/w/WelkinHawk.java | 9 ++++----- Mage/src/main/java/mage/abilities/AbilityImpl.java | 2 +- .../common/EndOfCombatTriggeredAbility.java | 7 +++---- .../abilities/effects/common/ExileAllEffect.java | 7 +++---- .../common/LookLibraryTopCardTargetPlayerEffect.java | 2 +- .../common/counter/AddCountersSourceEffect.java | 8 +++++++- .../effects/common/discard/DiscardTargetEffect.java | 2 +- .../java/mage/abilities/keyword/FlyingAbility.java | 9 ++++----- .../java/mage/abilities/keyword/ShroudAbility.java | 2 +- .../mage/abilities/keyword/VigilanceAbility.java | 5 ++--- 28 files changed, 78 insertions(+), 74 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/Bequeathal.java b/Mage.Sets/src/mage/cards/b/Bequeathal.java index 0243f77892..e1c6f12f92 100644 --- a/Mage.Sets/src/mage/cards/b/Bequeathal.java +++ b/Mage.Sets/src/mage/cards/b/Bequeathal.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; public class Bequeathal extends CardImpl { public Bequeathal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -59,7 +59,7 @@ public class Bequeathal extends CardImpl { this.addAbility(ability); // When enchanted creature dies, you draw two cards. - this.addAbility( new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(2), "enchanted creature")); + this.addAbility(new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(2).setText("you draw two cards"), "enchanted creature")); } public Bequeathal(final Bequeathal card) { diff --git a/Mage.Sets/src/mage/cards/c/ChillHaunting.java b/Mage.Sets/src/mage/cards/c/ChillHaunting.java index 4b678c0411..4a9dfd5fff 100644 --- a/Mage.Sets/src/mage/cards/c/ChillHaunting.java +++ b/Mage.Sets/src/mage/cards/c/ChillHaunting.java @@ -50,7 +50,7 @@ public class ChillHaunting extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); // As an additional cost to cast Chill Haunting, exile X creature cards from your graveyard. - this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"))); + this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"), true)); // Target creature gets -X/-X until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java b/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java index b8a5262544..2c641e7c7d 100644 --- a/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java +++ b/Mage.Sets/src/mage/cards/d/DecreeOfSilence.java @@ -45,7 +45,7 @@ import mage.constants.CardType; import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.StaticFilters; +import mage.filter.FilterSpell; import mage.target.TargetSpell; /** @@ -55,19 +55,19 @@ import mage.target.TargetSpell; public class DecreeOfSilence extends CardImpl { public DecreeOfSilence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{6}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{6}{U}{U}"); // Whenever an opponent casts a spell, counter that spell and put a depletion counter on Decree of Silence. If there are three or more depletion counters on Decree of Silence, sacrifice it. Effect effect = new CounterTargetEffect(); effect.setText("counter that spell"); - Ability ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_SPELL, - false, SetTargetPointer.SPELL); + Ability ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, effect, new FilterSpell("a spell"), + false, SetTargetPointer.SPELL); effect = new AddCountersSourceEffect(CounterType.DEPLETION.createInstance()); effect.setText("and put a depletion counter on {this}."); ability.addEffect(effect); ability.addEffect(new ConditionalOneShotEffect(new SacrificeSourceEffect(), - new SourceHasCounterCondition(CounterType.DEPLETION, 3, Integer.MAX_VALUE), - " If there are three or more depletion counters on {this}, sacrifice it")); + new SourceHasCounterCondition(CounterType.DEPLETION, 3, Integer.MAX_VALUE), + " If there are three or more depletion counters on {this}, sacrifice it")); this.addAbility(ability); // Cycling {4}{U}{U} this.addAbility(new CyclingAbility(new ManaCostsImpl("{4}{U}{U}"))); diff --git a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java index 836cc8fd16..eb0cb15d73 100644 --- a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java +++ b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java @@ -52,7 +52,7 @@ import mage.players.Player; public class EntropicSpecter extends CardImpl { public EntropicSpecter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.SPECTER); this.subtype.add(SubType.SPIRIT); @@ -105,7 +105,7 @@ class CardsInTargetPlayerHandCount implements DynamicValue { @Override public String getMessage() { - return "cards in chosen opponents hand"; + return "cards in the chosen player's hand"; } @Override diff --git a/Mage.Sets/src/mage/cards/m/MercurialKite.java b/Mage.Sets/src/mage/cards/m/MercurialKite.java index b36bc71d32..b20f7107ec 100644 --- a/Mage.Sets/src/mage/cards/m/MercurialKite.java +++ b/Mage.Sets/src/mage/cards/m/MercurialKite.java @@ -56,7 +56,7 @@ public class MercurialKite extends CardImpl { // Whenever Mercurial Kite deals combat damage to a creature, tap that creature. That creature doesn't untap during its controller's next untap step. Ability ability; ability = new DealsDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), true, false, true); - ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("and it")); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(". That creature")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MischievousQuanar.java b/Mage.Sets/src/mage/cards/m/MischievousQuanar.java index cb89d7fe41..646992201e 100644 --- a/Mage.Sets/src/mage/cards/m/MischievousQuanar.java +++ b/Mage.Sets/src/mage/cards/m/MischievousQuanar.java @@ -53,19 +53,19 @@ import mage.target.TargetSpell; public class MischievousQuanar extends CardImpl { public MischievousQuanar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); // {3}{U}{U}: Turn Mischievous Quanar face down. Effect effect = new BecomesFaceDownCreatureEffect(Duration.Custom, BecomesFaceDownCreatureEffect.FaceDownType.MANUAL); - effect.setText("Turn Michievous Quanar face down. (It becomes a 2/2 creature.)"); + effect.setText("Turn {this} face down. (It becomes a 2/2 creature.)"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}{U}{U}"))); - + // Morph {1}{U}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}{U}"))); - + // When Mischievous Quanar is turned face up, copy target instant or sorcery spell. You may choose new targets for that copy. Effect effect2 = new CopyTargetSpellEffect(); effect2.setText("copy target instant or sorcery spell. You may choose new targets for that copy"); diff --git a/Mage.Sets/src/mage/cards/o/OneWithNature.java b/Mage.Sets/src/mage/cards/o/OneWithNature.java index 55c0e36dab..6f4e7097f9 100644 --- a/Mage.Sets/src/mage/cards/o/OneWithNature.java +++ b/Mage.Sets/src/mage/cards/o/OneWithNature.java @@ -52,7 +52,7 @@ import java.util.UUID; public class OneWithNature extends CardImpl { public OneWithNature(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -61,12 +61,13 @@ public class OneWithNature extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.PutLandInPlay)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Whenever enchanted creature deals combat damage to a player, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. ability = new DealsDamageToAPlayerAttachedTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay) + .setText("you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library."), "enchanted creature", true, false, true, TargetController.ANY); - this.addAbility(ability); + this.addAbility(ability); } public OneWithNature(final OneWithNature card) { diff --git a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java index 45441eb9e5..4e19cb2918 100644 --- a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java +++ b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java @@ -45,7 +45,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RavenGuildInitiate extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("Bird you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird you control"); static { filter.add(new SubtypePredicate(SubType.BIRD)); diff --git a/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java b/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java index 03fcbeb245..070b57e686 100644 --- a/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java +++ b/Mage.Sets/src/mage/cards/r/ReapingTheGraves.java @@ -43,12 +43,11 @@ import mage.target.common.TargetCardInYourGraveyard; public class ReapingTheGraves extends CardImpl { public ReapingTheGraves(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // Return target creature card from your graveyard to your hand. this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setText("Return target creature card from your graveyard to your hand.")); // Storm this.addAbility(new StormAbility()); } diff --git a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java index 848f6ca74b..f46924f5b5 100644 --- a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java +++ b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java @@ -44,11 +44,11 @@ import mage.target.common.TargetControlledPermanent; public class ReapingTheRewards extends CardImpl { public ReapingTheRewards(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Buyback-Sacrifice a land. - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent())))); - + this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + // You gain 2 life. this.getSpellAbility().addEffect(new GainLifeEffect(2)); } diff --git a/Mage.Sets/src/mage/cards/r/RecklessOgre.java b/Mage.Sets/src/mage/cards/r/RecklessOgre.java index b21dc15a7d..59d93a7e8c 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessOgre.java +++ b/Mage.Sets/src/mage/cards/r/RecklessOgre.java @@ -44,13 +44,13 @@ import mage.constants.Duration; public class RecklessOgre extends CardImpl { public RecklessOgre(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.OGRE); this.power = new MageInt(3); this.toughness = new MageInt(2); // Whenever Reckless Ogre attacks alone, it gets +3/+0 until end of turn. - this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(3, 0, Duration.EndOfTurn))); + this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(3, 0, Duration.EndOfTurn).setText("it gets +3/+0 until end of turn"))); } public RecklessOgre(final RecklessOgre card) { diff --git a/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java b/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java index a41add973c..46eafe8f82 100644 --- a/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java +++ b/Mage.Sets/src/mage/cards/r/RewardTheFaithful.java @@ -42,10 +42,11 @@ import mage.target.TargetPlayer; public class RewardTheFaithful extends CardImpl { public RewardTheFaithful(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Any number of target players each gain life equal to the highest converted mana cost among permanents you control. - this.getSpellAbility().addEffect(new GainLifeTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new GainLifeTargetEffect(new HighestConvertedManaCostValue()) + .setText("Any number of target players each gain life equal to the highest converted mana cost among permanents you control.")); this.getSpellAbility().addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); } diff --git a/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java b/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java index dee50f94aa..093ec1376a 100644 --- a/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java +++ b/Mage.Sets/src/mage/cards/s/ScaldingSalamander.java @@ -66,7 +66,7 @@ public class ScaldingSalamander extends CardImpl { // Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls. this.addAbility(new AttacksTriggeredAbility( new DamageAllEffect(1, filter), true, - "Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls" + "Whenever Scalding Salamander attacks, you may have it deal 1 damage to each creature without flying defending player controls." )); } diff --git a/Mage.Sets/src/mage/cards/s/SpikeCannibal.java b/Mage.Sets/src/mage/cards/s/SpikeCannibal.java index c87670061d..876717e641 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeCannibal.java +++ b/Mage.Sets/src/mage/cards/s/SpikeCannibal.java @@ -53,13 +53,13 @@ import mage.game.permanent.Permanent; public class SpikeCannibal extends CardImpl { public SpikeCannibal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Cannibal enters the battlefield with a +1/+1 counter on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), "Spike Cannibal enters the battlefield with a +1/+1 counter on it")); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), "with a +1/+1 counter on it")); // When Spike Cannibal enters the battlefield, move all +1/+1 counters from all creatures onto it. this.addAbility(new EntersBattlefieldTriggeredAbility(new SpikeCannibalEffect())); diff --git a/Mage.Sets/src/mage/cards/s/SpikeRogue.java b/Mage.Sets/src/mage/cards/s/SpikeRogue.java index b7a6efd2dd..a27148a327 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeRogue.java +++ b/Mage.Sets/src/mage/cards/s/SpikeRogue.java @@ -54,23 +54,23 @@ import mage.target.common.TargetCreaturePermanent; public class SpikeRogue extends CardImpl { public SpikeRogue(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Rogue enters the battlefield with two +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)))); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), "with two +1/+1 counters on it")); // {2}, Remove a +1/+1 counter from Spike Rogue: Put a +1/+1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // {2}, Remove a +1/+1 counter from a creature you control: Put a +1/+1 counter on Spike Rogue. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new GenericManaCost(2)); - ability2.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent(), true), CounterType.P1P1)); + ability2.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true), CounterType.P1P1)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/s/SpikeWeaver.java b/Mage.Sets/src/mage/cards/s/SpikeWeaver.java index 7c7f90cbdc..d30ff8cce9 100644 --- a/Mage.Sets/src/mage/cards/s/SpikeWeaver.java +++ b/Mage.Sets/src/mage/cards/s/SpikeWeaver.java @@ -53,21 +53,21 @@ import mage.target.common.TargetCreaturePermanent; public class SpikeWeaver extends CardImpl { public SpikeWeaver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.SPIKE); this.power = new MageInt(0); this.toughness = new MageInt(0); // Spike Weaver enters the battlefield with three +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)))); - + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it")); + // {2}, Remove a +1/+1 counter from Spike Weaver: Put a +1/+1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // {1}, Remove a +1/+1 counter from Spike Weaver: Prevent all combat damage that would be dealt this turn. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true), new GenericManaCost(1)); ability2.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); diff --git a/Mage.Sets/src/mage/cards/t/TorrentOfFire.java b/Mage.Sets/src/mage/cards/t/TorrentOfFire.java index d07918ce53..6f6501f595 100644 --- a/Mage.Sets/src/mage/cards/t/TorrentOfFire.java +++ b/Mage.Sets/src/mage/cards/t/TorrentOfFire.java @@ -42,10 +42,12 @@ import mage.target.common.TargetCreatureOrPlayer; public class TorrentOfFire extends CardImpl { public TorrentOfFire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}"); // Torrent of Fire deals damage equal to the highest converted mana cost among permanents you control to target creature or player. - this.getSpellAbility().addEffect(new DamageTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new DamageTargetEffect(new HighestConvertedManaCostValue()) + .setText("{this} deals damage to target creature or player equal to the highest converted mana cost among permanents you control.") + ); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/cards/v/VengefulDead.java b/Mage.Sets/src/mage/cards/v/VengefulDead.java index 5c2eec5918..863da2da6a 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulDead.java +++ b/Mage.Sets/src/mage/cards/v/VengefulDead.java @@ -43,15 +43,15 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author fireshoes */ public class VengefulDead extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another Zombie"); - + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie"); + static { filter.add(new SubtypePredicate(SubType.ZOMBIE)); } public VengefulDead(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/w/WelkinHawk.java b/Mage.Sets/src/mage/cards/w/WelkinHawk.java index 8996177ae0..81cb90cac0 100644 --- a/Mage.Sets/src/mage/cards/w/WelkinHawk.java +++ b/Mage.Sets/src/mage/cards/w/WelkinHawk.java @@ -44,9 +44,8 @@ import mage.target.common.TargetCardInLibrary; * * @author fireshoes */ - public class WelkinHawk extends CardImpl { - + private static final FilterCard filter = new FilterCard("card named Welkin Hawk"); static { @@ -54,16 +53,16 @@ public class WelkinHawk extends CardImpl { } public WelkinHawk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(1); this.toughness = new MageInt(1); // Flying this.addAbility(FlyingAbility.getInstance()); - + // When Welkin Hawk dies, you may search your library for a card named Welkin Hawk, reveal that card, put it into your hand, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 3fc2020dd7..8e52732e5d 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -773,7 +773,7 @@ public abstract class AbilityImpl implements Ability { } if (!costs.isEmpty()) { if (sbRule.length() > 0) { - sbRule.append(','); + sbRule.append(", "); } sbRule.append(costs.getText()); } diff --git a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java index cdff752da7..3c332a232b 100644 --- a/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EndOfCombatTriggeredAbility.java @@ -15,7 +15,6 @@ import mage.game.events.GameEvent; * * @author LevelX2 */ - public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { public EndOfCombatTriggeredAbility(Effect effect, boolean optional) { @@ -35,7 +34,7 @@ public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.END_COMBAT_STEP_PRE; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { return true; @@ -43,6 +42,6 @@ public class EndOfCombatTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "At the end of combat, " + super.getRule(); + return "At end of combat, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java index 5c076adc38..ec46d23210 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAllEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import java.util.List; @@ -52,6 +51,7 @@ public class ExileAllEffect extends OneShotEffect { public ExileAllEffect(FilterPermanent filter) { this(filter, null, null); } + public ExileAllEffect(FilterPermanent filter, UUID exileId, String exileZone) { super(Outcome.Exile); this.filter = filter; @@ -77,19 +77,18 @@ public class ExileAllEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for (Permanent permanent: permanents) { + for (Permanent permanent : permanents) { controller.moveCardToExileWithInfo(permanent, exileId, exileZone, source.getSourceId(), game, Zone.BATTLEFIELD, true); } return true; } return false; - } private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Exile all ").append(filter.getMessage()); + sb.append("exile all ").append(filter.getMessage()); staticText = sb.toString(); } } 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 bf7c607f31..3081206ac6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java @@ -106,7 +106,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { sb.append(CardUtil.numberToText(amount)); sb.append(" cards "); } else { - sb.append(" card "); + sb.append("card "); } sb.append("of target player's library"); if (putToGraveyard) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 1f28040a73..9376340acf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -152,14 +152,20 @@ public class AddCountersSourceEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); sb.append("put "); + boolean plural = true; if (counter.getCount() > 1) { sb.append(CardUtil.numberToText(counter.getCount())).append(' '); } else if (amount.toString().equals("X") && amount.getMessage().isEmpty()) { sb.append("X "); } else { sb.append("a "); + plural = false; } - sb.append(counter.getName().toLowerCase()).append(" counter on {this}"); + sb.append(counter.getName().toLowerCase()).append(" counter"); + if (plural) { + sb.append('s'); + } + sb.append(" on {this}"); if (!amount.getMessage().isEmpty()) { sb.append(" for each ").append(amount.getMessage()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java index a053e6f256..4bf488649b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardTargetEffect.java @@ -108,7 +108,7 @@ public class DiscardTargetEffect extends OneShotEffect { } sb.append(" discards "); if (amount.toString().equals("1")) { - sb.append(" a card"); + sb.append("a card"); } else { sb.append(CardUtil.numberToText(amount.toString())).append(" cards"); } diff --git a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java index 86d243c675..1e0bf34cb1 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlyingAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.abilities.Ability; @@ -46,7 +45,7 @@ import java.io.ObjectStreamException; */ public class FlyingAbility extends EvasionAbility implements MageSingleton { - private static final FlyingAbility instance = new FlyingAbility(); + private static final FlyingAbility instance = new FlyingAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -62,7 +61,7 @@ public class FlyingAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Flying"; + return "flying"; } @Override @@ -91,7 +90,7 @@ class FlyingEffect extends RestrictionEffect implements MageSingleton { public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { return blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId()) || blocker.getAbilities().containsKey(ReachAbility.getInstance().getId()) - || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype(SubType.DRAGON, game)) ; + || (game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_DRAGON, source, blocker.getControllerId(), game) && attacker.hasSubtype(SubType.DRAGON, game)); } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java b/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java index 53e32db450..556f9addb9 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ShroudAbility.java @@ -56,7 +56,7 @@ public class ShroudAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Shroud"; + return "shroud"; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java b/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java index a4d5f29d5a..13925a8ee3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/VigilanceAbility.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class VigilanceAbility extends StaticAbility implements MageSingleton { - private static final VigilanceAbility instance = new VigilanceAbility(); + private static final VigilanceAbility instance = new VigilanceAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class VigilanceAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Vigilance"; + return "vigilance"; } @Override From bc2bfba02a9924cb83b6aa56439d37c740f44c13 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 18:28:22 -0400 Subject: [PATCH 65/68] more text fixes --- .../src/mage/cards/a/AgelessSentinels.java | 2 +- Mage.Sets/src/mage/cards/a/AlphaStatus.java | 2 +- Mage.Sets/src/mage/cards/a/AncientOoze.java | 16 +++++----- Mage.Sets/src/mage/cards/b/BlackCarriage.java | 10 +++---- Mage.Sets/src/mage/cards/b/BrownOuphe.java | 2 +- .../src/mage/cards/c/CabalConditioning.java | 6 ++-- .../mage/cards/c/ClergyOfTheHolyNimbus.java | 8 ++--- Mage.Sets/src/mage/cards/c/CoalitionFlag.java | 4 +-- .../src/mage/cards/d/DaughterOfAutumn.java | 1 + Mage.Sets/src/mage/cards/d/DivineLight.java | 6 ++-- Mage.Sets/src/mage/cards/d/DwarvenPatrol.java | 6 ++-- Mage.Sets/src/mage/cards/g/GreatDefender.java | 4 ++- Mage.Sets/src/mage/cards/i/IceCave.java | 15 +++++----- Mage.Sets/src/mage/cards/i/Illuminate.java | 14 ++++----- Mage.Sets/src/mage/cards/j/Jilt.java | 8 ++--- Mage.Sets/src/mage/cards/j/Jokulmorder.java | 12 ++++---- .../src/mage/cards/k/KarplusanMinotaur.java | 30 ++++++++----------- Mage.Sets/src/mage/cards/l/LastCaress.java | 6 ++-- .../src/mage/cards/m/MinotaurTactician.java | 16 +++++----- .../src/mage/cards/p/PhyrexianEtchings.java | 6 ++-- .../src/mage/cards/r/RimefeatherOwl.java | 2 +- Mage.Sets/src/mage/cards/r/RonomUnicorn.java | 7 ++--- Mage.Sets/src/mage/cards/r/Rust.java | 2 +- .../src/mage/cards/s/ShimmeringMirage.java | 4 +-- Mage.Sets/src/mage/cards/s/SurgingAether.java | 7 +++-- Mage.Sets/src/mage/cards/t/TranquilPath.java | 5 ++-- .../src/mage/cards/u/UnnaturalSelection.java | 2 +- .../common/CantBeRegeneratedSourceEffect.java | 2 +- .../effects/common/ExileSourceEffect.java | 2 +- .../RevealLibraryPutIntoHandEffect.java | 2 +- .../BecomesBasicLandTargetEffect.java | 2 +- ...BecomesChosenCreatureTypeTargetEffect.java | 2 +- .../continuous/BecomesColorTargetEffect.java | 20 +++++++------ .../abilities/keyword/ProtectionAbility.java | 3 +- .../mage/abilities/keyword/RippleAbility.java | 8 ++--- .../main/java/mage/filter/StaticFilters.java | 1 + .../filter/common/FilterBlockingCreature.java | 5 ++-- 37 files changed, 124 insertions(+), 126 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java index fe9bd4e47b..95e308c9f3 100644 --- a/Mage.Sets/src/mage/cards/a/AgelessSentinels.java +++ b/Mage.Sets/src/mage/cards/a/AgelessSentinels.java @@ -87,7 +87,7 @@ public class AgelessSentinels extends CardImpl { public AgelessSentinelsEffect() { super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); - staticText = "it becomes a Bird Giant, "; + staticText = "it becomes a Bird Giant,"; } public AgelessSentinelsEffect(final AgelessSentinelsEffect effect) { diff --git a/Mage.Sets/src/mage/cards/a/AlphaStatus.java b/Mage.Sets/src/mage/cards/a/AlphaStatus.java index 3e106f9fab..9701f4a523 100644 --- a/Mage.Sets/src/mage/cards/a/AlphaStatus.java +++ b/Mage.Sets/src/mage/cards/a/AlphaStatus.java @@ -109,6 +109,6 @@ class AlphaStatusDynamicValue implements DynamicValue { @Override public String getMessage() { - return "each other creature on the battlefield that shares a creature type with it"; + return "other creature on the battlefield that shares a creature type with it"; } } diff --git a/Mage.Sets/src/mage/cards/a/AncientOoze.java b/Mage.Sets/src/mage/cards/a/AncientOoze.java index b1d652fff1..e6b1542c56 100644 --- a/Mage.Sets/src/mage/cards/a/AncientOoze.java +++ b/Mage.Sets/src/mage/cards/a/AncientOoze.java @@ -52,15 +52,17 @@ import mage.game.permanent.Permanent; public class AncientOoze extends CardImpl { public AncientOoze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.OOZE); - this.color.setGreen(true); + this.color.setGreen(true); this.power = new MageInt(0); this.toughness = new MageInt(0); - // Ancient Ooze's power and toughness are each equal to the total converted mana cost of other creatures you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new AncientOozePowerToughnessValue(), Duration.EndOfGame))); + // Ancient Ooze's power and toughness are each equal to the total converted mana cost of other creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new AncientOozePowerToughnessValue(), Duration.EndOfGame) + .setText("{this}'s power and toughness are each equal to the total converted mana cost of other creatures you control.") + )); } public AncientOoze(final AncientOoze card) { @@ -74,12 +76,12 @@ public class AncientOoze extends CardImpl { } class AncientOozePowerToughnessValue implements DynamicValue { - + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { int value = 0; - for(Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), sourceAbility.getControllerId(), game)){ - if(creature != null && !sourceAbility.getSourceId().equals(creature.getId())){ + for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), sourceAbility.getControllerId(), game)) { + if (creature != null && !sourceAbility.getSourceId().equals(creature.getId())) { value += creature.getConvertedManaCost(); } } diff --git a/Mage.Sets/src/mage/cards/b/BlackCarriage.java b/Mage.Sets/src/mage/cards/b/BlackCarriage.java index 98e36a38c4..1c6908c9af 100644 --- a/Mage.Sets/src/mage/cards/b/BlackCarriage.java +++ b/Mage.Sets/src/mage/cards/b/BlackCarriage.java @@ -52,21 +52,21 @@ import mage.target.common.TargetControlledCreaturePermanent; public class BlackCarriage extends CardImpl { public BlackCarriage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.HORSE); this.power = new MageInt(4); this.toughness = new MageInt(4); // Trample this.addAbility(TrampleAbility.getInstance()); - + // Black Carriage doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Sacrifice a creature: Untap Black Carriage. Activate this ability only during your upkeep. - this.addAbility(new ConditionalActivatedAbility(Zone.BATTLEFIELD, + this.addAbility(new ConditionalActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))), - new IsStepCondition(PhaseStep.UPKEEP), null)); + new IsStepCondition(PhaseStep.UPKEEP), "Sacrifice a creature: Untap {this}. Activate this ability only during your upkeep.")); } public BlackCarriage(final BlackCarriage card) { diff --git a/Mage.Sets/src/mage/cards/b/BrownOuphe.java b/Mage.Sets/src/mage/cards/b/BrownOuphe.java index 0e8014f032..1810831dd0 100644 --- a/Mage.Sets/src/mage/cards/b/BrownOuphe.java +++ b/Mage.Sets/src/mage/cards/b/BrownOuphe.java @@ -53,7 +53,7 @@ import java.util.UUID; */ public class BrownOuphe extends CardImpl { - private final static FilterStackObject filter = new FilterStackObject("ability from an artifact source"); + private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { filter.add(new ArtifactSourcePredicate()); diff --git a/Mage.Sets/src/mage/cards/c/CabalConditioning.java b/Mage.Sets/src/mage/cards/c/CabalConditioning.java index bd96b2cd0f..5ac53f18b1 100644 --- a/Mage.Sets/src/mage/cards/c/CabalConditioning.java +++ b/Mage.Sets/src/mage/cards/c/CabalConditioning.java @@ -42,10 +42,12 @@ import mage.target.TargetPlayer; public class CabalConditioning extends CardImpl { public CabalConditioning(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{B}"); // Any number of target players each discard a number of cards equal to the highest converted mana cost among permanents you control. - this.getSpellAbility().addEffect(new DiscardTargetEffect(new HighestConvertedManaCostValue())); + this.getSpellAbility().addEffect(new DiscardTargetEffect(new HighestConvertedManaCostValue()) + .setText("Any number of target players each discard a number of cards equal to the highest converted mana cost among permanents you control.") + ); this.getSpellAbility().addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); } diff --git a/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java b/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java index f8c2be4edd..5022878c6f 100644 --- a/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java +++ b/Mage.Sets/src/mage/cards/c/ClergyOfTheHolyNimbus.java @@ -53,7 +53,7 @@ import mage.game.permanent.Permanent; public class ClergyOfTheHolyNimbus extends CardImpl { public ClergyOfTheHolyNimbus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); @@ -61,7 +61,7 @@ public class ClergyOfTheHolyNimbus extends CardImpl { // If Clergy of the Holy Nimbus would be destroyed, regenerate it. this.addAbility(new SimpleStaticAbility(Zone.ALL, new ClergyOfTheHolyNimbusReplacementEffect())); - + // {1}: Clergy of the Holy Nimbus can't be regenerated this turn. Only any opponent may activate this ability. this.addAbility(new ActivateOnlyByOpponentActivatedAbility(Zone.BATTLEFIELD, new CantBeRegeneratedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}"))); } @@ -90,7 +90,7 @@ class ClergyOfTheHolyNimbusReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent ClergyOfTheHolyNimbus = game.getPermanent(event.getTargetId()); - if (ClergyOfTheHolyNimbus != null + if (ClergyOfTheHolyNimbus != null && event.getAmount() == 0) { // 1=noRegen if (ClergyOfTheHolyNimbus.regenerate(source.getSourceId(), game)) { game.informPlayers(source.getSourceObject(game).getName() + " has been regenerated."); @@ -116,4 +116,4 @@ class ClergyOfTheHolyNimbusReplacementEffect extends ReplacementEffectImpl { return new ClergyOfTheHolyNimbusReplacementEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index 811512b53e..a5e996cd2d 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -45,7 +45,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetControlledCreaturePermanent; /** * @@ -59,7 +59,7 @@ public class CoalitionFlag extends CardImpl { this.subtype.add(SubType.AURA); // Enchant creature you control - TargetPermanent auraTarget = new TargetCreaturePermanent(); + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); diff --git a/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java b/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java index 07fa354c4a..464864afe5 100644 --- a/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java +++ b/Mage.Sets/src/mage/cards/d/DaughterOfAutumn.java @@ -71,6 +71,7 @@ public class DaughterOfAutumn extends CardImpl { // {W}: The next 1 damage that would be dealt to target white creature this turn is dealt to Daughter of Autumn instead. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DaughterOfAutumnPreventDamageTargetEffect(Duration.EndOfTurn, 1), new ManaCostsImpl("{W}")); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); } public DaughterOfAutumn(final DaughterOfAutumn card) { diff --git a/Mage.Sets/src/mage/cards/d/DivineLight.java b/Mage.Sets/src/mage/cards/d/DivineLight.java index 3035f362f8..ca3e4380ec 100644 --- a/Mage.Sets/src/mage/cards/d/DivineLight.java +++ b/Mage.Sets/src/mage/cards/d/DivineLight.java @@ -50,10 +50,12 @@ public class DivineLight extends CardImpl { } public DivineLight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Prevent all damage that would be dealt this turn to creatures you control. - this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter)); + this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter) + .setText("Prevent all damage that would be dealt this turn to creatures you control.") + ); } public DivineLight(final DivineLight card) { diff --git a/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java b/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java index 41403091af..9cb25e7bf9 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenPatrol.java @@ -46,18 +46,18 @@ import mage.filter.predicate.mageobject.ColorPredicate; /** * * @author LoneFox - + * */ public class DwarvenPatrol extends CardImpl { - private static final FilterSpell filter = new FilterSpell("nonred spell"); + private static final FilterSpell filter = new FilterSpell("a nonred spell"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.RED))); } public DwarvenPatrol(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.DWARF); this.power = new MageInt(4); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/g/GreatDefender.java b/Mage.Sets/src/mage/cards/g/GreatDefender.java index d7c8a83240..101c127b17 100644 --- a/Mage.Sets/src/mage/cards/g/GreatDefender.java +++ b/Mage.Sets/src/mage/cards/g/GreatDefender.java @@ -48,7 +48,9 @@ public class GreatDefender extends CardImpl { // Target creature gets +0/+X until end of turn, where X is its converted mana cost. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true) + .setText("Target creature gets +0/+X until end of turn, where X is its converted mana cost.") + ); } public GreatDefender(final GreatDefender card) { diff --git a/Mage.Sets/src/mage/cards/i/IceCave.java b/Mage.Sets/src/mage/cards/i/IceCave.java index 4a8234f99a..188f79f42b 100644 --- a/Mage.Sets/src/mage/cards/i/IceCave.java +++ b/Mage.Sets/src/mage/cards/i/IceCave.java @@ -52,11 +52,10 @@ import mage.players.Player; public class IceCave extends CardImpl { public IceCave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); // Whenever a player casts a spell, any other player may pay that spell's mana cost. If a player does, counter the spell. (Mana cost includes color.) - this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new IceCaveEffect(), StaticFilters.FILTER_SPELL, false, SetTargetPointer.SPELL)); + this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new IceCaveEffect(), StaticFilters.FILTER_A_SPELL, false, SetTargetPointer.SPELL)); } public IceCave(final IceCave card) { @@ -90,17 +89,17 @@ class IceCaveEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Spell spell = (Spell) game.getStack().getStackObject(targetPointer.getFirst(game, source)); - if(sourcePermanent != null && spell != null && controller != null) { + if (sourcePermanent != null && spell != null && controller != null) { Player spellController = game.getPlayer(spell.getControllerId()); Cost cost = new ManaCostsImpl(spell.getSpellAbility().getManaCosts().getText()); - if(spellController != null) { + if (spellController != null) { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - if(player != null && player != spellController) { + if (player != null && player != spellController) { cost.clearPaid(); - if(cost.canPay(source, source.getSourceId(), player.getId(), game) + if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(outcome, "Pay " + cost.getText() + " to counter " + spell.getIdName() + '?', source, game)) { - if(cost.pay(source, game, source.getSourceId(), playerId, false, null)) { + if (cost.pay(source, game, source.getSourceId(), playerId, false, null)) { game.informPlayers(player.getLogName() + " pays" + cost.getText() + " to counter " + spell.getIdName() + '.'); game.getStack().counter(spell.getId(), source.getSourceId(), game); return true; diff --git a/Mage.Sets/src/mage/cards/i/Illuminate.java b/Mage.Sets/src/mage/cards/i/Illuminate.java index a357d8f9a4..9ee484a69a 100644 --- a/Mage.Sets/src/mage/cards/i/Illuminate.java +++ b/Mage.Sets/src/mage/cards/i/Illuminate.java @@ -47,7 +47,7 @@ import mage.target.common.TargetCreaturePermanent; public class Illuminate extends CardImpl { public Illuminate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); // Kicker {2}{R} and/or {3}{U} KickerAbility kickerAbility = new KickerAbility("{2}{R}"); @@ -57,13 +57,13 @@ public class Illuminate extends CardImpl { this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue())); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DamageTargetControllerEffect(new ManacostVariableValue()), - new KickedCostCondition("{2}{R}"), - "If {this} was kicked with its {2}{R} kicker, it deals X damage to that creature's controller.")); + new DamageTargetControllerEffect(new ManacostVariableValue()), + new KickedCostCondition("{2}{R}"), + "If {this} was kicked with its {2}{R} kicker, it deals X damage to that creature's controller.")); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DrawCardSourceControllerEffect(new ManacostVariableValue()), - new KickedCostCondition("{3}{U}"), - "If {this} was kicked with its {3}{U} kicker, you draw X cards.")); + new DrawCardSourceControllerEffect(new ManacostVariableValue()), + new KickedCostCondition("{3}{U}"), + " If {this} was kicked with its {3}{U} kicker, you draw X cards.")); } diff --git a/Mage.Sets/src/mage/cards/j/Jilt.java b/Mage.Sets/src/mage/cards/j/Jilt.java index 799208d43d..2f3d30c68e 100644 --- a/Mage.Sets/src/mage/cards/j/Jilt.java +++ b/Mage.Sets/src/mage/cards/j/Jilt.java @@ -53,11 +53,11 @@ import mage.target.targetpointer.SecondTargetPointer; public class Jilt extends CardImpl { public Jilt(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Kicker {1}{R} this.addAbility(new KickerAbility("{1}{R}")); - + // Return target creature to its owner's hand. If Jilt was kicked, it deals 2 damage to another target creature. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); Effect effect = new ConditionalOneShotEffect( @@ -66,11 +66,11 @@ public class Jilt extends CardImpl { "If {this} was kicked, it deals 2 damage to another target creature"); effect.setTargetPointer(new SecondTargetPointer()); this.getSpellAbility().addEffect(effect); - Target target = new TargetCreaturePermanent(new FilterCreaturePermanent("Target Creature: returned to Hand")); + Target target = new TargetCreaturePermanent(); target.setTargetTag(1); this.getSpellAbility().addTarget(target); } - + @Override public void adjustTargets(Ability ability, Game game) { if (ability instanceof SpellAbility && KickedCondition.instance.apply(game, ability)) { diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 87ce51cb02..3a785aa071 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -59,26 +59,26 @@ import java.util.UUID; public class Jokulmorder extends CardImpl { public Jokulmorder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}{U}"); this.subtype.add(SubType.LEVIATHAN); this.power = new MageInt(12); this.toughness = new MageInt(12); // Trample this.addAbility(TrampleAbility.getInstance()); - + // Jokulmorder enters the battlefield tapped. this.addAbility(new EntersBattlefieldTappedAbility()); - + // When Jokulmorder enters the battlefield, sacrifice it unless you sacrifice five lands. Effect effect = new SacrificeSourceUnlessPaysEffect( new SacrificeTargetCost(new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("five lands"), true))); effect.setText("sacrifice it unless you sacrifice five lands"); this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false)); - + // Jokulmorder doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Whenever you play an Island, you may untap Jokulmorder. this.addAbility(new JokulmorderTriggeredAbility()); } @@ -122,6 +122,6 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When you play an Island, you may untap {this}"; + return "Whenever you play an Island, you may untap {this}"; } } diff --git a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java index 8d21319da3..a244cd23b1 100644 --- a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java +++ b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java @@ -32,20 +32,15 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; -import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.CumulativeUpkeepAbility; 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.constants.Zone; -import mage.counters.CounterType; -import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -60,7 +55,7 @@ import mage.target.common.TargetOpponent; public class KarplusanMinotaur extends CardImpl { public KarplusanMinotaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.MINOTAUR); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(3); @@ -68,7 +63,7 @@ public class KarplusanMinotaur extends CardImpl { // Cumulative upkeep-Flip a coin. this.addAbility(new CumulativeUpkeepAbility(new KarplusanMinotaurCost())); - + // Whenever you win a coin flip, Karplusan Minotaur deals 1 damage to target creature or player. Ability abilityWin = new KarplusanMinotaurFlipWinTriggeredAbility(); abilityWin.addTarget(new TargetCreatureOrPlayer()); @@ -80,23 +75,22 @@ public class KarplusanMinotaur extends CardImpl { abilityLose.addTarget(new TargetCreatureOrPlayer()); this.addAbility(abilityLose); } - + @Override public void adjustTargets(Ability ability, Game game) { if (ability instanceof KarplusanMinotaurFlipLoseTriggeredAbility) { Player controller = game.getPlayer(ability.getControllerId()); - if(controller != null) { + if (controller != null) { UUID opponentId = null; - if(game.getOpponents(controller.getId()).size() > 1) { + if (game.getOpponents(controller.getId()).size() > 1) { Target target = new TargetOpponent(true); - if(controller.chooseTarget(Outcome.Neutral, target, ability, game)) { + if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) { opponentId = target.getFirstTarget(); } - } - else { + } else { opponentId = game.getOpponents(controller.getId()).iterator().next(); } - if(opponentId != null) { + if (opponentId != null) { ability.getTargets().get(0).setTargetController(opponentId); } } @@ -171,12 +165,12 @@ class KarplusanMinotaurFlipLoseTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you lose a coin flip, {this} deals 1 damage to target creature or player of an opponent's choice"; + return "Whenever you lose a coin flip, {this} deals 1 damage to target creature or player of an opponent's choice."; } } class KarplusanMinotaurCost extends CostImpl { - + KarplusanMinotaurCost() { this.text = "Flip a coin"; } @@ -188,7 +182,7 @@ class KarplusanMinotaurCost extends CostImpl { controller.flipCoin(game); this.paid = true; return true; - } + } return false; } @@ -202,7 +196,7 @@ class KarplusanMinotaurCost extends CostImpl { } return false; } - + @Override public KarplusanMinotaurCost copy() { return new KarplusanMinotaurCost(); diff --git a/Mage.Sets/src/mage/cards/l/LastCaress.java b/Mage.Sets/src/mage/cards/l/LastCaress.java index 3bc5473e34..e4652239ec 100644 --- a/Mage.Sets/src/mage/cards/l/LastCaress.java +++ b/Mage.Sets/src/mage/cards/l/LastCaress.java @@ -43,12 +43,12 @@ import mage.target.TargetPlayer; public class LastCaress extends CardImpl { public LastCaress(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); this.getSpellAbility().addEffect(new LoseLifeTargetEffect(1)); this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new GainLifeEffect(1)); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new GainLifeEffect(1).setText("and you gain 1 life")); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public LastCaress(final LastCaress card) { diff --git a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java index 27413e44db..c3e1cfbbe5 100644 --- a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java +++ b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java @@ -52,33 +52,33 @@ import java.util.UUID; * @author fireshoes */ public class MinotaurTactician extends CardImpl { - + private static final FilterControlledCreaturePermanent filterWhite = new FilterControlledCreaturePermanent(); private static final FilterControlledCreaturePermanent filterBlue = new FilterControlledCreaturePermanent(); - + static { filterWhite.add(new ColorPredicate(ObjectColor.WHITE)); filterBlue.add(new ColorPredicate(ObjectColor.BLUE)); } - + static final private String ruleWhite = "{this} gets +1/+1 as long as you control another white creature"; - - static final private String ruleBlue = "{this} gets +1/+1 as long as you control another white creature"; + + static final private String ruleBlue = "{this} gets +1/+1 as long as you control another blue creature"; public MinotaurTactician(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.MINOTAUR); this.power = new MageInt(1); this.toughness = new MageInt(1); // Haste this.addAbility(HasteAbility.getInstance()); - + // Minotaur Tactician gets +1/+1 as long as you control a white creature. Condition conditionWhite = new PermanentsOnTheBattlefieldCondition(filterWhite); Effect effectWhite = new ConditionalContinuousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), conditionWhite, ruleWhite); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effectWhite)); - + // Minotaur Tactician gets +1/+1 as long as you control a blue creature. Condition conditionBlue = new PermanentsOnTheBattlefieldCondition(filterBlue); Effect effectBlue = new ConditionalContinuousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), conditionBlue, ruleBlue); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java index 7734e59a99..bbf7e70191 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java @@ -28,11 +28,9 @@ package mage.cards.p; import java.util.UUID; -import mage.MageInt; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -59,7 +57,9 @@ public class PhyrexianEtchings extends CardImpl { this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.AGE)), false)); // When Phyrexian Etchings is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)))); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) + .setText("When {this} is put into a graveyard from the battlefield, you lose 2 life for each age counter on it") + )); } public PhyrexianEtchings(final PhyrexianEtchings card) { diff --git a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java index 9e89292b85..2b6e660201 100644 --- a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java +++ b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java @@ -135,6 +135,6 @@ class RimefeatherOwlEffect extends ContinuousEffectImpl { @Override public String getText(Mode mode) { - return "All nonland permanents are legendary"; + return "Permanents with ice counters on them are snow."; } } diff --git a/Mage.Sets/src/mage/cards/r/RonomUnicorn.java b/Mage.Sets/src/mage/cards/r/RonomUnicorn.java index bfcfb18f58..fe12934ca4 100644 --- a/Mage.Sets/src/mage/cards/r/RonomUnicorn.java +++ b/Mage.Sets/src/mage/cards/r/RonomUnicorn.java @@ -37,10 +37,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; import java.util.UUID; +import mage.target.common.TargetEnchantmentPermanent; /** * @@ -49,14 +48,14 @@ import java.util.UUID; public class RonomUnicorn extends CardImpl { public RonomUnicorn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.UNICORN); this.power = new MageInt(2); this.toughness = new MageInt(2); // Sacrifice Ronom Unicorn: Destroy target enchantment. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new SacrificeSourceCost()); - ability.addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); + ability.addTarget(new TargetEnchantmentPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Rust.java b/Mage.Sets/src/mage/cards/r/Rust.java index c1f5f4edc9..21dd121bf9 100644 --- a/Mage.Sets/src/mage/cards/r/Rust.java +++ b/Mage.Sets/src/mage/cards/r/Rust.java @@ -46,7 +46,7 @@ import mage.target.common.TargetActivatedOrTriggeredAbility; */ public class Rust extends CardImpl { - private final static FilterStackObject filter = new FilterStackObject("ability from an artifact source"); + private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source"); static { filter.add(new ArtifactSourcePredicate()); diff --git a/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java b/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java index 273b7bcb0f..47761a07bd 100644 --- a/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java +++ b/Mage.Sets/src/mage/cards/s/ShimmeringMirage.java @@ -43,13 +43,13 @@ import mage.target.common.TargetLandPermanent; public class ShimmeringMirage extends CardImpl { public ShimmeringMirage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Target land becomes the basic land type of your choice until end of turn. this.getSpellAbility().addEffect(new BecomesBasicLandTargetEffect(Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetLandPermanent()); // Draw a card. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public ShimmeringMirage(final ShimmeringMirage card) { diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index bb9a0b3a5f..1db14c65ce 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -42,13 +42,14 @@ import mage.target.TargetPermanent; public class SurgingAether extends CardImpl { public SurgingAether(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); - // Ripple 4 - this.addAbility(new RippleAbility(4)); // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent()); + + // Ripple 4 + this.addAbility(new RippleAbility(4)); } public SurgingAether(final SurgingAether card) { diff --git a/Mage.Sets/src/mage/cards/t/TranquilPath.java b/Mage.Sets/src/mage/cards/t/TranquilPath.java index de90b5056b..04d214cd1e 100644 --- a/Mage.Sets/src/mage/cards/t/TranquilPath.java +++ b/Mage.Sets/src/mage/cards/t/TranquilPath.java @@ -42,13 +42,12 @@ import mage.filter.common.FilterEnchantmentPermanent; public class TranquilPath extends CardImpl { public TranquilPath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}"); // Destroy all enchantments. this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterEnchantmentPermanent("enchantments"))); // Draw a card. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); } public TranquilPath(final TranquilPath card) { diff --git a/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java b/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java index d069036dbf..aabc4cf8ff 100644 --- a/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java +++ b/Mage.Sets/src/mage/cards/u/UnnaturalSelection.java @@ -45,7 +45,7 @@ import mage.target.common.TargetCreaturePermanent; public class UnnaturalSelection extends CardImpl { public UnnaturalSelection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); // {1}: Choose a creature type other than Wall. Target creature becomes that type until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesChosenCreatureTypeTargetEffect(true), new GenericManaCost(1)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java index 5d21c6e346..ad1aca5584 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java @@ -78,7 +78,7 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect return staticText; } StringBuilder sb = new StringBuilder(); - sb.append(" {this} can't be regenerated"); + sb.append("{this} can't be regenerated"); if (!duration.toString().isEmpty()) { sb.append(' '); if (duration == Duration.EndOfTurn) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java index 60efb497e9..455d3a5466 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileSourceEffect.java @@ -57,7 +57,7 @@ public class ExileSourceEffect extends OneShotEffect { */ public ExileSourceEffect(boolean toUniqueExileZone) { super(Outcome.Exile); - staticText = "Exile {this}"; + staticText = "exile {this}"; this.toUniqueExileZone = toUniqueExileZone; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java index 5d8965fde1..d0b5710466 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealLibraryPutIntoHandEffect.java @@ -117,7 +117,7 @@ public class RevealLibraryPutIntoHandEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("Reveal the top "); + StringBuilder sb = new StringBuilder("reveal the top "); sb.append(CardUtil.numberToText(amountCards.toString())).append(" cards of your library. Put all "); sb.append(filter.getMessage()); sb.append(" revealed this way into your hand and the rest "); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java index e843082305..4d0bb0703e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesBasicLandTargetEffect.java @@ -191,7 +191,7 @@ public class BecomesBasicLandTargetEffect extends ContinuousEffectImpl { private String setText() { StringBuilder sb = new StringBuilder(); if (chooseLandType) { - sb.append("Target land becomes the basic land type of your choice "); + sb.append("Target land becomes the basic land type of your choice"); } else { sb.append("Target land becomes a "); int i = 1; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index 6a21fcf093..d97d8f9ea9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -26,7 +26,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { super(Outcome.BoostCreature); this.nonWall = nonWall; if(nonWall) { - staticText = "choose a creature type other than wall, target creature's type becomes that type until end of turn"; + staticText = "choose a creature type other than wall. Target creature becomes that type until end of turn"; } else { staticText = "target creature becomes the creature type of your choice until end of turn"; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java index abf36d2d3a..c437a9404f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorTargetEffect.java @@ -52,12 +52,13 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { /** * Set the color of a spell or permanent - * - * @param duration + * + * @param duration */ public BecomesColorTargetEffect(Duration duration) { this(null, duration, null); } + public BecomesColorTargetEffect(ObjectColor setColor, Duration duration) { this(setColor, duration, null); } @@ -78,7 +79,7 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return; - } + } if (setColor == null) { ChoiceColor choice = new ChoiceColor(); while (!choice.isChosen()) { @@ -95,9 +96,8 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { if (!game.isSimulation()) { game.informPlayers(controller.getLogName() + " has chosen the color: " + setColor.toString()); } - } - - + } + super.init(source, game); //To change body of generated methods, choose Tools | Templates. } @@ -109,11 +109,11 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { } if (setColor != null) { boolean objectFound = false; - for (UUID targetId :targetPointer.getTargets(game, source)) { + for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject targetObject = game.getObject(targetId); if (targetObject != null) { objectFound = true; - targetObject.getColor(game).setColor(setColor); + targetObject.getColor(game).setColor(setColor); } } if (!objectFound && this.getDuration() == Duration.Custom) { @@ -143,7 +143,9 @@ public class BecomesColorTargetEffect extends ContinuousEffectImpl { } else { sb.append(setColor.getDescription()); } - sb.append(' ').append(duration.toString()); + if (!duration.toString().equals("")) { + sb.append(' ').append(duration.toString()); + } return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java index 1e8c5adc2b..46471af292 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java @@ -32,7 +32,6 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.StaticAbility; import mage.cards.Card; -import mage.constants.CardType; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterCard; @@ -90,7 +89,7 @@ public class ProtectionAbility extends StaticAbility { @Override public String getRule() { - return "Protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); + return "protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); } public boolean canTarget(MageObject source, Game game) { diff --git a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java index dde3a57961..cf70a57336 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java @@ -56,13 +56,11 @@ public class RippleAbility extends TriggeredAbilityImpl { return new RippleAbility(this); } - @Override public String getRule() { - return "Ripple " + rippleNumber + " (When you cast this spell, you may reveal the top " + CardUtil.numberToText(rippleNumber) + " cards of your library. You may cast any revealed cards with the same name as this spell without paying their mana costs. Put the rest on the bottom of your library.)"; + return "ripple " + rippleNumber + " (When you cast this spell, you may reveal the top " + CardUtil.numberToText(rippleNumber) + " cards of your library. You may cast any revealed cards with the same name as this spell without paying their mana costs. Put the rest on the bottom of your library.)"; } - } class RippleEffect extends OneShotEffect { @@ -84,13 +82,12 @@ class RippleEffect extends OneShotEffect { return new RippleEffect(this); } - @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player != null) { - if (!player.chooseUse(Outcome.Neutral, "Reveal " + rippleNumber + " cards from the top of your library?", source, game)){ + if (!player.chooseUse(Outcome.Neutral, "Reveal " + rippleNumber + " cards from the top of your library?", source, game)) { return true; //fizzle } // reveal to/**/p cards from library @@ -123,4 +120,3 @@ class RippleEffect extends OneShotEffect { } } - diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 42676a1b12..60c7d931a3 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -69,6 +69,7 @@ public final class StaticFilters { = (FilterSpell) new FilterSpell("noncreature spell").add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); public static final FilterSpell FILTER_SPELL = new FilterSpell(); + public static final FilterSpell FILTER_A_SPELL = new FilterSpell("a spell"); public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELL = new FilterSpell("instant or sorcery spell"); public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELLS = new FilterSpell("instant or sorcery spells"); diff --git a/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java b/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java index 7e6aa11769..896517c0bf 100644 --- a/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java +++ b/Mage/src/main/java/mage/filter/common/FilterBlockingCreature.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.filter.common; import mage.filter.predicate.permanent.BlockingPredicate; @@ -37,7 +36,7 @@ import mage.filter.predicate.permanent.BlockingPredicate; public class FilterBlockingCreature extends FilterCreaturePermanent { public FilterBlockingCreature() { - this("Blocking creature"); + this("blocking creature"); } public FilterBlockingCreature(String name) { From 00755356502810ccab90198c39fdc0e0cd2e1a7f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 6 Oct 2017 22:00:06 -0400 Subject: [PATCH 66/68] so many text fixes --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 2 +- .../src/mage/cards/b/BellowingAegisaur.java | 2 +- .../src/mage/cards/c/CaptivatingCrew.java | 2 +- .../src/mage/cards/d/DarienKingOfKjeldor.java | 7 ++++--- Mage.Sets/src/mage/cards/d/DralnusPet.java | 4 ++-- .../src/mage/cards/d/DreamcallerSiren.java | 2 +- .../src/mage/cards/d/DroverOfTheMighty.java | 2 +- .../src/mage/cards/f/FathomFleetCaptain.java | 2 +- .../src/mage/cards/f/FreyalisesRadiance.java | 2 +- Mage.Sets/src/mage/cards/g/GaeasMight.java | 5 +++-- .../src/mage/cards/h/HierophantsChalice.java | 2 +- .../mage/cards/h/HuatliDinosaurKnight.java | 4 +++- .../mage/cards/j/JaceIngeniousMindMage.java | 6 +++--- Mage.Sets/src/mage/cards/j/JacesSentinel.java | 2 +- Mage.Sets/src/mage/cards/j/Jokulmorder.java | 2 +- .../src/mage/cards/k/KrovikanWhispers.java | 7 +++---- .../src/mage/cards/l/LightningStorm.java | 4 ++-- .../src/mage/cards/l/LookoutsDispersal.java | 2 +- .../src/mage/cards/m/MakeshiftMunitions.java | 2 +- .../src/mage/cards/m/MaliciousAdvice.java | 6 +++--- .../src/mage/cards/m/MaraudingLooter.java | 2 +- .../src/mage/cards/m/MarchOfTheDrowned.java | 3 +-- Mage.Sets/src/mage/cards/m/MercurialKite.java | 4 ++-- .../src/mage/cards/m/MinotaurTactician.java | 4 ++-- .../src/mage/cards/p/PhyrexianEtchings.java | 2 +- .../src/mage/cards/p/PhyrexianTyranny.java | 2 +- .../mage/cards/p/PriestOfTheWakeningSun.java | 2 +- Mage.Sets/src/mage/cards/r/RaidersWake.java | 2 +- .../src/mage/cards/r/RavenGuildInitiate.java | 2 +- Mage.Sets/src/mage/cards/r/RazingSnidd.java | 6 +++--- Mage.Sets/src/mage/cards/r/RegisaurAlpha.java | 2 +- Mage.Sets/src/mage/cards/r/RevelInRiches.java | 2 +- Mage.Sets/src/mage/cards/r/RiggingRunner.java | 2 +- .../src/mage/cards/r/RimefeatherOwl.java | 7 ++++++- Mage.Sets/src/mage/cards/r/RuthlessKnave.java | 2 +- Mage.Sets/src/mage/cards/s/SamitePilgrim.java | 4 ++-- Mage.Sets/src/mage/cards/s/SanctumSeeker.java | 2 +- .../src/mage/cards/s/ShipwreckLooter.java | 2 +- Mage.Sets/src/mage/cards/s/SirensRuse.java | 2 +- .../src/mage/cards/s/SkyshipWeatherlight.java | 6 +++--- .../src/mage/cards/s/SnappingSailback.java | 2 +- Mage.Sets/src/mage/cards/s/SpellSwindle.java | 2 +- .../src/mage/cards/s/StarOfExtinction.java | 2 +- .../src/mage/cards/s/SunbirdsInvocation.java | 10 +++++++++ Mage.Sets/src/mage/cards/s/Sunscour.java | 7 ++++--- Mage.Sets/src/mage/cards/s/SurgingAether.java | 6 +++--- Mage.Sets/src/mage/cards/t/TempestCaller.java | 2 +- Mage.Sets/src/mage/cards/u/UrzasGuilt.java | 5 ++--- .../src/mage/cards/v/VanquishersBanner.java | 2 +- .../src/mage/cards/v/VeldraneOfSengir.java | 6 +++--- .../src/mage/cards/v/VerdantSunsAvatar.java | 4 ++-- .../src/mage/cards/v/VraskaRelicSeeker.java | 2 +- .../src/mage/cards/w/WakerOfTheWilds.java | 10 +++++++-- .../src/mage/cards/w/WaterspoutElemental.java | 2 +- .../abilities/common/CantBlockAbility.java | 2 +- .../condition/common/RaidCondition.java | 5 ++++- .../common/CantBeRegeneratedSourceEffect.java | 1 - .../common/LookLibraryControllerEffect.java | 2 +- ...PreventAllDamageByAllPermanentsEffect.java | 18 ++++++++++++---- .../common/PreventDamageToSourceEffect.java | 8 ++++++- .../TapAllTargetPlayerControlsEffect.java | 9 ++++---- .../combat/CantBlockAttachedEffect.java | 5 ++++- ...BecomesChosenCreatureTypeTargetEffect.java | 2 +- .../continuous/BecomesCreatureAllEffect.java | 3 +-- .../GainAbilityControlledSpellsEffect.java | 2 +- .../common/counter/AddCountersAllEffect.java | 3 ++- ...SearchLibraryGraveyardPutInHandEffect.java | 2 +- .../abilities/keyword/DeathtouchAbility.java | 7 ++----- .../mage/abilities/keyword/FearAbility.java | 10 ++++----- .../keyword/IndestructibleAbility.java | 21 +++++++++---------- 70 files changed, 163 insertions(+), 126 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index 5b92f7cd1f..cd291187e8 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -56,7 +56,7 @@ import java.util.*; */ public class AdmiralBeckettBrass extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other Pirates you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Pirates you control"); private static final FilterNonlandPermanent filter2 = new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"); static { diff --git a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java index 7c2db5f657..e7dbc3daa4 100644 --- a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java +++ b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java @@ -49,7 +49,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class BellowingAegisaur extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each other creature you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature you control"); static { filter.add(new ControllerPredicate(TargetController.YOU)); diff --git a/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java b/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java index 5e90f4283d..ae87461a4f 100644 --- a/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java +++ b/Mage.Sets/src/mage/cards/c/CaptivatingCrew.java @@ -54,7 +54,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class CaptivatingCrew extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("target creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); diff --git a/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java b/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java index 5aa34573f3..3581920ec0 100644 --- a/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java +++ b/Mage.Sets/src/mage/cards/d/DarienKingOfKjeldor.java @@ -53,7 +53,7 @@ import mage.players.Player; public class DarienKingOfKjeldor extends CardImpl { public DarienKingOfKjeldor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -74,6 +74,7 @@ public class DarienKingOfKjeldor extends CardImpl { return new DarienKingOfKjeldor(this); } } + class DarienKingOfKjeldorTriggeredAbility extends TriggeredAbilityImpl { public DarienKingOfKjeldorTriggeredAbility() { @@ -105,7 +106,7 @@ class DarienKingOfKjeldorTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you are dealt damage, you may create that many 1/1 white Soldier creature tokens."; + return "Whenever you're dealt damage, you may create that many 1/1 white Soldier creature tokens."; } } @@ -133,4 +134,4 @@ class DarienKingOfKjeldorEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DralnusPet.java b/Mage.Sets/src/mage/cards/d/DralnusPet.java index 267078de93..8627591833 100644 --- a/Mage.Sets/src/mage/cards/d/DralnusPet.java +++ b/Mage.Sets/src/mage/cards/d/DralnusPet.java @@ -65,7 +65,7 @@ import mage.players.Player; public class DralnusPet extends CardImpl { public DralnusPet(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -77,7 +77,7 @@ public class DralnusPet extends CardImpl { this.addAbility(new KickerAbility(kickerCosts)); // If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost. Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.instance, - "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost", ""); + "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java b/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java index 5677be80ed..67709860a0 100644 --- a/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java +++ b/Mage.Sets/src/mage/cards/d/DreamcallerSiren.java @@ -84,7 +84,7 @@ public class DreamcallerSiren extends CardImpl { ability.addTarget(new TargetNonlandPermanent(0, 2, false)); this.addAbility(new ConditionalTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(filter), - "when {this} enters the battlefield, if you control another Pirate, tap up to two nonland permanents.")); + "when {this} enters the battlefield, if you control another Pirate, tap up to two target nonland permanents.")); } public DreamcallerSiren(final DreamcallerSiren card) { diff --git a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java index a9b0bb1bb6..43a6e62840 100644 --- a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java +++ b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java @@ -46,7 +46,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class DroverOfTheMighty extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("a Dinosaur"); + private static final FilterPermanent filter = new FilterPermanent("Dinosaur"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java index 72f6e09eae..9d7913136a 100644 --- a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java @@ -76,7 +76,7 @@ public class FathomFleetCaptain extends CardImpl { this.addAbility(new ConditionalTriggeredAbility( new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new PirateToken()), new GenericManaCost(2)), false), new PermanentsOnTheBattlefieldCondition(filter), - "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace")); + "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, create a 2/2 black Pirate creature token with menace")); } public FathomFleetCaptain(final FathomFleetCaptain card) { diff --git a/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java b/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java index f1beb8ac1e..ab44a4e85f 100644 --- a/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java +++ b/Mage.Sets/src/mage/cards/f/FreyalisesRadiance.java @@ -48,7 +48,7 @@ import mage.filter.predicate.mageobject.SupertypePredicate; */ public class FreyalisesRadiance extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(); + private static final FilterPermanent filter = new FilterPermanent("snow permanents"); static { filter.add(new SupertypePredicate(SuperType.SNOW)); diff --git a/Mage.Sets/src/mage/cards/g/GaeasMight.java b/Mage.Sets/src/mage/cards/g/GaeasMight.java index ad18c3dc5e..52daaeeabc 100644 --- a/Mage.Sets/src/mage/cards/g/GaeasMight.java +++ b/Mage.Sets/src/mage/cards/g/GaeasMight.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; @@ -43,12 +44,12 @@ import mage.target.common.TargetCreaturePermanent; public class GaeasMight extends CardImpl { public GaeasMight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); // Domain - Target creature gets +1/+1 until end of turn for each basic land type among lands you control. this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(), new DomainValue(), Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public GaeasMight(final GaeasMight card) { diff --git a/Mage.Sets/src/mage/cards/h/HierophantsChalice.java b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java index 7773026a68..73e175fd7c 100644 --- a/Mage.Sets/src/mage/cards/h/HierophantsChalice.java +++ b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java @@ -50,7 +50,7 @@ public class HierophantsChalice extends CardImpl { // When Hierophant's Chalice enters the battlefield, target opponent loses 1 life and you gain 1 life. Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(1), false); - ability.addEffect(new GainLifeEffect(1)); + ability.addEffect(new GainLifeEffect(1).setText("and you gain one life.")); Target target = new TargetOpponent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java b/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java index a7f28c381b..593d385681 100644 --- a/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java +++ b/Mage.Sets/src/mage/cards/h/HuatliDinosaurKnight.java @@ -74,7 +74,9 @@ public class HuatliDinosaurKnight extends CardImpl { this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +2: Put two +1/+1 counters on up to one target Dinosaur you control. - Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2); + Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)) + .setText("Put two +1/+1 counters on up to one target Dinosaur you control."), 2 + ); ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java index cfc7cfeb04..5d8fdb57f0 100644 --- a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java +++ b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java @@ -40,7 +40,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.SuperType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; +import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; /** @@ -61,11 +61,11 @@ public class JaceIngeniousMindMage extends CardImpl { this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1)); // +1: Untap all creatures you control. - this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(FILTER_PERMANENT_CREATURES), 1)); + this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURES), 1)); // -9: Gain control of up to three target creatures. Ability ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.Custom), -9); - ability.addTarget(new TargetCreaturePermanent(0, 3)); + ability.addTarget(new TargetCreaturePermanent(0, 3, StaticFilters.FILTER_PERMANENT_CREATURES, false)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JacesSentinel.java b/Mage.Sets/src/mage/cards/j/JacesSentinel.java index a9288ece7d..5d27ac6b60 100644 --- a/Mage.Sets/src/mage/cards/j/JacesSentinel.java +++ b/Mage.Sets/src/mage/cards/j/JacesSentinel.java @@ -77,7 +77,7 @@ public class JacesSentinel extends CardImpl { ability.addEffect(new ConditionalContinuousEffect( new CantBeBlockedSourceEffect(), new PermanentsOnTheBattlefieldCondition(filter), - "and has can't be blocked")); + "and can't be blocked")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 3a785aa071..99c8ba7525 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -122,6 +122,6 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you play an Island, you may untap {this}"; + return "Whenever you play an Island, you may untap {this}."; } } diff --git a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java index e454889dc4..06287397b1 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java @@ -28,7 +28,6 @@ package mage.cards.k; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; @@ -36,7 +35,6 @@ import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.costs.OrCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -76,7 +74,9 @@ public class KrovikanWhispers extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); // When Krovikan Whispers is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)))); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) + .setText("you lose 2 life for each age counter on it.") + )); } public KrovikanWhispers(final KrovikanWhispers card) { @@ -88,4 +88,3 @@ public class KrovikanWhispers extends CardImpl { return new KrovikanWhispers(this); } } - diff --git a/Mage.Sets/src/mage/cards/l/LightningStorm.java b/Mage.Sets/src/mage/cards/l/LightningStorm.java index 9c856fcada..c69e97fc88 100644 --- a/Mage.Sets/src/mage/cards/l/LightningStorm.java +++ b/Mage.Sets/src/mage/cards/l/LightningStorm.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class LightningStorm extends CardImpl { public LightningStorm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{R}"); // Lightning Storm deals X damage to target creature or player, where X is 3 plus the number of charge counters on it. Effect effect = new DamageTargetEffect(new LightningStormCountCondition(CounterType.CHARGE)); @@ -67,7 +67,7 @@ public class LightningStorm extends CardImpl { // Discard a land card: Put two charge counters on Lightning Storm. You may choose a new target for it. Any player may activate this ability but only if Lightning Storm is on the stack. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.STACK, new LightningStormAddCounterEffect(), - new DiscardTargetCost(new TargetCardInHand(new FilterLandCard()))); + new DiscardTargetCost(new TargetCardInHand(new FilterLandCard("a land card")))); ability.setMayActivate(TargetController.ANY); ability.addEffect(new InfoEffect("Any player may activate this ability but only if {this} is on the stack")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java index 556e32d4fd..2aa8d97464 100644 --- a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java +++ b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java @@ -49,7 +49,7 @@ import mage.target.TargetSpell; */ public class LookoutsDispersal extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Pirate"); static { filter.add(new SubtypePredicate(SubType.PIRATE)); diff --git a/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java b/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java index ca6c60abd1..2be6c83d59 100644 --- a/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java +++ b/Mage.Sets/src/mage/cards/m/MakeshiftMunitions.java @@ -49,7 +49,7 @@ import mage.target.common.TargetCreatureOrPlayer; */ public class MakeshiftMunitions extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature"); static { filter.add(Predicates.or( diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java index a9d044d72e..05479e1007 100644 --- a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java +++ b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java @@ -59,18 +59,18 @@ public class MaliciousAdvice extends CardImpl { } public MaliciousAdvice(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}{B}"); // Tap X target artifacts, creatures, and/or lands. You lose X life. Effect effect = new TapTargetEffect(); - effect.setText("Tap X target artifacts, creatures, and/or lands"); + effect.setText("X target artifacts, creatures, and/or lands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue())); } @Override public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { + if (ability instanceof SpellAbility) { ability.getTargets().clear(); ability.addTarget(new TargetPermanent(ability.getManaCostsToPay().getX(), filter)); } diff --git a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java index c87a6297a6..609f05cdab 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java @@ -61,7 +61,7 @@ public class MaraudingLooter extends CardImpl { RaidCondition.instance, "Raid — At the beginning of your end step, " + "if you attacked with a creature this turn, " - + "you may draw a card. If you do, discard a card"); + + "you may draw a card. If you do, discard a card."); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java index 393917cb02..cd3f5d8513 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java @@ -30,7 +30,6 @@ package mage.cards.m; import java.util.UUID; import mage.abilities.Mode; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; -import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -57,7 +56,7 @@ public class MarchOfTheDrowned extends CardImpl { // Choose one — // &bull; Return target creature card from your graveyard to your hand. - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); // &bull; Return two target Pirate cards from your graveyard to your hand. Mode mode = new Mode(); diff --git a/Mage.Sets/src/mage/cards/m/MercurialKite.java b/Mage.Sets/src/mage/cards/m/MercurialKite.java index b20f7107ec..c359ce3197 100644 --- a/Mage.Sets/src/mage/cards/m/MercurialKite.java +++ b/Mage.Sets/src/mage/cards/m/MercurialKite.java @@ -46,7 +46,7 @@ import mage.constants.SubType; public class MercurialKite extends CardImpl { public MercurialKite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -56,7 +56,7 @@ public class MercurialKite extends CardImpl { // Whenever Mercurial Kite deals combat damage to a creature, tap that creature. That creature doesn't untap during its controller's next untap step. Ability ability; ability = new DealsDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), true, false, true); - ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(". That creature")); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("That creature")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java index c3e1cfbbe5..b9203d8288 100644 --- a/Mage.Sets/src/mage/cards/m/MinotaurTactician.java +++ b/Mage.Sets/src/mage/cards/m/MinotaurTactician.java @@ -61,9 +61,9 @@ public class MinotaurTactician extends CardImpl { filterBlue.add(new ColorPredicate(ObjectColor.BLUE)); } - static final private String ruleWhite = "{this} gets +1/+1 as long as you control another white creature"; + static final private String ruleWhite = "{this} gets +1/+1 as long as you control a white creature"; - static final private String ruleBlue = "{this} gets +1/+1 as long as you control another blue creature"; + static final private String ruleBlue = "{this} gets +1/+1 as long as you control a blue creature"; public MinotaurTactician(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java index bbf7e70191..7c1aa54950 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianEtchings.java @@ -58,7 +58,7 @@ public class PhyrexianEtchings extends CardImpl { // When Phyrexian Etchings is put into a graveyard from the battlefield, you lose 2 life for each age counter on it. this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new LoseLifeSourceControllerEffect(new MultipliedValue(new CountersSourceCount(CounterType.AGE), 2)) - .setText("When {this} is put into a graveyard from the battlefield, you lose 2 life for each age counter on it") + .setText("you lose 2 life for each age counter on it") )); } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java index 92d11254b4..4816a99a9e 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java @@ -100,7 +100,7 @@ class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}"; + return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}."; } } diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java index 7e40ff5721..6abcebba75 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -59,7 +59,7 @@ import mage.target.common.TargetCardInLibrary; */ public class PriestOfTheWakeningSun extends CardImpl { - private static final FilterCard filter = new FilterCard("a Dinosaur card"); + private static final FilterCard filter = new FilterCard("Dinosaur card"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/r/RaidersWake.java b/Mage.Sets/src/mage/cards/r/RaidersWake.java index 8ac022dbdb..0cfd603bf1 100644 --- a/Mage.Sets/src/mage/cards/r/RaidersWake.java +++ b/Mage.Sets/src/mage/cards/r/RaidersWake.java @@ -58,7 +58,7 @@ public class RaidersWake extends CardImpl { // Raid — At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card. Ability ability = new ConditionalTriggeredAbility( new BeginningOfEndStepTriggeredAbility(new DiscardTargetEffect(1), TargetController.YOU, false), RaidCondition.instance, - "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card"); + "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card."); ability.addTarget(new TargetOpponent()); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java index 4e19cb2918..5269c61f26 100644 --- a/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java +++ b/Mage.Sets/src/mage/cards/r/RavenGuildInitiate.java @@ -45,7 +45,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RavenGuildInitiate extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird you control"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Bird"); static { filter.add(new SubtypePredicate(SubType.BIRD)); diff --git a/Mage.Sets/src/mage/cards/r/RazingSnidd.java b/Mage.Sets/src/mage/cards/r/RazingSnidd.java index f0aff98ea6..6e66ea6cc6 100644 --- a/Mage.Sets/src/mage/cards/r/RazingSnidd.java +++ b/Mage.Sets/src/mage/cards/r/RazingSnidd.java @@ -45,7 +45,7 @@ import mage.filter.predicate.mageobject.ColorPredicate; /** * * @author LoneFox - + * */ public class RazingSnidd extends CardImpl { @@ -56,7 +56,7 @@ public class RazingSnidd extends CardImpl { } public RazingSnidd(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -64,7 +64,7 @@ public class RazingSnidd extends CardImpl { // When Razing Snidd enters the battlefield, return a black or red creature you control to its owner's hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter), false)); // When Razing Snidd enters the battlefield, each player sacrifices a land. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeAllEffect(1, new FilterControlledLandPermanent("a land")), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeAllEffect(1, new FilterControlledLandPermanent("land")), false)); } public RazingSnidd(final RazingSnidd card) { diff --git a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java index e73c5e301f..fb603c77eb 100644 --- a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java +++ b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java @@ -52,7 +52,7 @@ import mage.game.permanent.token.DinosaurToken; */ public class RegisaurAlpha extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("other Dinosaurss you control"); + private static final FilterPermanent filter = new FilterPermanent("Dinosaurs"); static { filter.add(new SubtypePredicate(SubType.DINOSAUR)); diff --git a/Mage.Sets/src/mage/cards/r/RevelInRiches.java b/Mage.Sets/src/mage/cards/r/RevelInRiches.java index 2fde790bda..3e757cb225 100644 --- a/Mage.Sets/src/mage/cards/r/RevelInRiches.java +++ b/Mage.Sets/src/mage/cards/r/RevelInRiches.java @@ -53,7 +53,7 @@ import mage.game.permanent.token.TreasureToken; */ public class RevelInRiches extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls"); private static final FilterPermanent filter2 = new FilterPermanent("Treasures"); static { diff --git a/Mage.Sets/src/mage/cards/r/RiggingRunner.java b/Mage.Sets/src/mage/cards/r/RiggingRunner.java index 9b6576fa95..b60adefa57 100644 --- a/Mage.Sets/src/mage/cards/r/RiggingRunner.java +++ b/Mage.Sets/src/mage/cards/r/RiggingRunner.java @@ -60,7 +60,7 @@ public class RiggingRunner extends CardImpl { // Raid — Rigging Runner enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.instance, - "Raid — {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "Raid — {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java index 2b6e660201..0ffb468b39 100644 --- a/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java +++ b/Mage.Sets/src/mage/cards/r/RimefeatherOwl.java @@ -87,7 +87,12 @@ public class RimefeatherOwl extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter2), Duration.EndOfGame))); // {1}{snow}: Put an ice counter on target permanent. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.ICE.createInstance()), new ManaCostsImpl("{1}{S}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new AddCountersTargetEffect(CounterType.ICE.createInstance()) + .setText("Put an ice counter on target permanent."), + new ManaCostsImpl("{1}{S}") + ); ability.addTarget(new TargetPermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java index c78724c8d2..96f7b85fda 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java @@ -53,7 +53,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RuthlessKnave extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("three three Treasures"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("three Treasures"); static { filter.add(new SubtypePredicate(SubType.TREASURE)); diff --git a/Mage.Sets/src/mage/cards/s/SamitePilgrim.java b/Mage.Sets/src/mage/cards/s/SamitePilgrim.java index ab148f89a2..8aa8e03e3f 100644 --- a/Mage.Sets/src/mage/cards/s/SamitePilgrim.java +++ b/Mage.Sets/src/mage/cards/s/SamitePilgrim.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; public class SamitePilgrim extends CardImpl { public SamitePilgrim(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(1); @@ -57,6 +57,7 @@ public class SamitePilgrim extends CardImpl { // Domain - {T}: Prevent the next X damage that would be dealt to target creature this turn, where X is the number of basic land types among lands you control. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SamitePilgrimPreventDamageToTargetEffect(), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } @@ -72,7 +73,6 @@ public class SamitePilgrim extends CardImpl { class SamitePilgrimPreventDamageToTargetEffect extends PreventionEffectImpl { - public SamitePilgrimPreventDamageToTargetEffect() { super(Duration.EndOfTurn, Integer.MAX_VALUE, false, true); staticText = "Prevent the next X damage that would be dealt to target creature this turn, where X is the number of basic land types among lands you control."; diff --git a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java index ec8e8d81f6..cc1f8076e9 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java @@ -47,7 +47,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class SanctumSeeker extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Vampire you control attacks"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Vampire you control"); static { filter.add(new SubtypePredicate(SubType.VAMPIRE)); diff --git a/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java index 0a8d7e92a7..dc6f2eb24b 100644 --- a/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java +++ b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java @@ -58,7 +58,7 @@ public class ShipwreckLooter extends CardImpl { Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1, true)), RaidCondition.instance, - "Raid - When {this} enters the battlefield,if you attacked with a creature this turn, you may draw a card. If you do, discard a card."); + "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, you may draw a card. If you do, discard a card."); this.addAbility(ability, new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/SirensRuse.java b/Mage.Sets/src/mage/cards/s/SirensRuse.java index 58ec90f304..f9a040d090 100644 --- a/Mage.Sets/src/mage/cards/s/SirensRuse.java +++ b/Mage.Sets/src/mage/cards/s/SirensRuse.java @@ -69,7 +69,7 @@ class SirensRuseEffect extends ExileTargetForSourceEffect { SirensRuseEffect() { super(); - this.staticText = "Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card."; + this.staticText = "Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card."; } SirensRuseEffect(final SirensRuseEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java b/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java index 53dd9426f8..6ee53ae9fd 100644 --- a/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java +++ b/Mage.Sets/src/mage/cards/s/SkyshipWeatherlight.java @@ -37,7 +37,7 @@ import mage.util.CardUtil; public class SkyshipWeatherlight extends CardImpl { public SkyshipWeatherlight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); addSuperType(SuperType.LEGENDARY); // When Skyship Weatherlight enters the battlefield, search your library for any number of artifact and/or creature cards and exile them. Then shuffle your library. @@ -73,7 +73,7 @@ class SkyshipWeatherlightEffect extends SearchEffect { public SkyshipWeatherlightEffect() { super(new TargetCardInLibrary(0, Integer.MAX_VALUE, filter), Outcome.Neutral); - this.staticText = "search your library for any number of artifact and/or creature cards and remove them from the game. Then shuffle your library"; + this.staticText = "search your library for any number of artifact and/or creature cards and exile them. Then shuffle your library"; } @@ -114,7 +114,7 @@ class SkyshipWeatherlightEffect2 extends OneShotEffect { public SkyshipWeatherlightEffect2() { super(Outcome.ReturnToHand); - this.staticText = "Choose a card at random that was removed from the game with {this}. Put that card into your hand"; + this.staticText = "Choose a card at random that was exiled with {this}. Put that card into its owner's hand"; } public SkyshipWeatherlightEffect2(final SkyshipWeatherlightEffect2 effect) { diff --git a/Mage.Sets/src/mage/cards/s/SnappingSailback.java b/Mage.Sets/src/mage/cards/s/SnappingSailback.java index 7a7d1468d6..2fc3f7f494 100644 --- a/Mage.Sets/src/mage/cards/s/SnappingSailback.java +++ b/Mage.Sets/src/mage/cards/s/SnappingSailback.java @@ -58,7 +58,7 @@ public class SnappingSailback extends CardImpl { // Enrage — Whenever Snapping Sailback is dealt damage, put a +1/+1 counter on it. this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)) - .setText("put a +1/+1 counter on it"), false)); + .setText("put a +1/+1 counter on it"), false, true)); } public SnappingSailback(final SnappingSailback card) { diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java index 6745cc8009..ff0a1baae8 100644 --- a/Mage.Sets/src/mage/cards/s/SpellSwindle.java +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -69,7 +69,7 @@ class SpellSwindleEffect extends OneShotEffect { public SpellSwindleEffect() { super(Outcome.Detriment); staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " - + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool"; + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool\""; } public SpellSwindleEffect(final SpellSwindleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/StarOfExtinction.java b/Mage.Sets/src/mage/cards/s/StarOfExtinction.java index 1fdb4a3469..15e6c31a9a 100644 --- a/Mage.Sets/src/mage/cards/s/StarOfExtinction.java +++ b/Mage.Sets/src/mage/cards/s/StarOfExtinction.java @@ -47,7 +47,7 @@ public class StarOfExtinction extends CardImpl { // Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker. this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DamageAllEffect(20, new FilterCreatureOrPlaneswalkerPermanent("each creature and each planeswalker"))); + this.getSpellAbility().addEffect(new DamageAllEffect(20, new FilterCreatureOrPlaneswalkerPermanent("creature and each planeswalker"))); this.getSpellAbility().addTarget(new TargetLandPermanent()); } diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 0b934660f8..815955a089 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -105,6 +105,16 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi public SunbirdsInvocationTriggeredAbility copy() { return new SunbirdsInvocationTriggeredAbility(this); } + + @Override + public String getRule() { + return "Whenever you cast a spell from your hand, " + + "reveal the top X cards of your library, " + + "where X is that spell's converted mana cost. " + + "You may cast a card revealed this way with " + + "converted mana cost X or less without paying its mana cost." + + " Put the rest on the bottom of your library in a random order."; + } } class SunbirdsInvocationEffect extends OneShotEffect { diff --git a/Mage.Sets/src/mage/cards/s/Sunscour.java b/Mage.Sets/src/mage/cards/s/Sunscour.java index 7649c08e97..aca679b76b 100644 --- a/Mage.Sets/src/mage/cards/s/Sunscour.java +++ b/Mage.Sets/src/mage/cards/s/Sunscour.java @@ -36,7 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.FilterCard; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCardInHand; @@ -47,18 +47,19 @@ import mage.target.common.TargetCardInHand; public class Sunscour extends CardImpl { private static final FilterCard filter = new FilterCard("two white cards"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); } public Sunscour(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}{W}"); // You may exile two white cards from your hand rather than pay Sunscour's mana cost. this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(2, filter)))); // Destroy all creatures. - this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterCreaturePermanent())); + this.getSpellAbility().addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES)); } public Sunscour(final Sunscour card) { diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index 1db14c65ce..ccb530ace5 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -44,12 +44,12 @@ public class SurgingAether extends CardImpl { public SurgingAether(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); + // Ripple 4 + this.addAbility(new RippleAbility(4)); + // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent()); - - // Ripple 4 - this.addAbility(new RippleAbility(4)); } public SurgingAether(final SurgingAether card) { diff --git a/Mage.Sets/src/mage/cards/t/TempestCaller.java b/Mage.Sets/src/mage/cards/t/TempestCaller.java index 94ee292caa..7910dfa185 100644 --- a/Mage.Sets/src/mage/cards/t/TempestCaller.java +++ b/Mage.Sets/src/mage/cards/t/TempestCaller.java @@ -54,7 +54,7 @@ public class TempestCaller extends CardImpl { this.toughness = new MageInt(3); // When Tempest Caller enters the battlefield, tap all creatures target opponent controls. - Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures target opponent controls"))); + Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures"))); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/u/UrzasGuilt.java b/Mage.Sets/src/mage/cards/u/UrzasGuilt.java index 76400716c3..a3224df09e 100644 --- a/Mage.Sets/src/mage/cards/u/UrzasGuilt.java +++ b/Mage.Sets/src/mage/cards/u/UrzasGuilt.java @@ -43,13 +43,12 @@ import mage.constants.CardType; public class UrzasGuilt extends CardImpl { public UrzasGuilt(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{B}"); // Each player draws two cards, then discards three cards, then loses 4 life. this.getSpellAbility().addEffect(new DrawCardAllEffect(2)); Effect effect = new DiscardEachPlayerEffect(3, false); - effect.setText("then discards three cards"); + effect.setText("then discards three cards,"); this.getSpellAbility().addEffect(effect); effect = new LoseLifeAllPlayersEffect(4); effect.setText("then loses 4 life"); diff --git a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java index 105e7c99ff..58af23ab79 100644 --- a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java +++ b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java @@ -128,6 +128,6 @@ class DrawCardIfCreatureTypeAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you cast a creature spell of the chosen type, draw a card"; + return "Whenever you cast a creature spell of the chosen type, draw a card."; } } diff --git a/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java b/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java index 056e7011d6..f50e6011d4 100644 --- a/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java +++ b/Mage.Sets/src/mage/cards/v/VeldraneOfSengir.java @@ -50,7 +50,7 @@ import mage.constants.Zone; public class VeldraneOfSengir extends CardImpl { public VeldraneOfSengir(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); @@ -58,8 +58,8 @@ public class VeldraneOfSengir extends CardImpl { this.toughness = new MageInt(5); // {1}{B}{B}: Veldrane of Sengir gets -3/-0 and gains forestwalk until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-3, -0, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}{B}")); - ability.addEffect(new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-3, -0, Duration.EndOfTurn).setText("{this} gets -3/-0"), new ManaCostsImpl("{1}{B}{B}")); + ability.addEffect(new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn).setText("and gains forestwalk until end of turn")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java index 7a75f45fd1..c930ee1887 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java +++ b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java @@ -59,7 +59,7 @@ public class VerdantSunsAvatar extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(5); - // When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness. + // Whenever Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness. this.addAbility(new VerdantSunsAvatarTriggeredAbility()); } @@ -104,7 +104,7 @@ class VerdantSunsAvatarTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When {this} or another creature enters the battlefield under your control, " + super.getRule(); + return "Whenever {this} or another creature enters the battlefield under your control, " + super.getRule(); } @Override diff --git a/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java index 4795a2c12f..0ca53b9549 100644 --- a/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java +++ b/Mage.Sets/src/mage/cards/v/VraskaRelicSeeker.java @@ -90,7 +90,7 @@ class VraskaRelicSeekerDestroyEffect extends OneShotEffect { VraskaRelicSeekerDestroyEffect() { super(Outcome.Benefit); - this.staticText = "Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with \"{T}, Sacrfice this artifact. Add one mana of any color to your mana pool.\""; + this.staticText = "Destroy target artifact, creature, or enchantment. Create a colorless Treasure artifact token with \"{T}, Sacrifice this artifact. Add one mana of any color to your mana pool.\""; } VraskaRelicSeekerDestroyEffect(final VraskaRelicSeekerDestroyEffect effect) { diff --git a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java index f9cbcd3f23..ab1ff75772 100644 --- a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java +++ b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java @@ -62,8 +62,14 @@ public class WakerOfTheWilds extends CardImpl { this.toughness = new MageInt(3); // {X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste that's still a land. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new ManacostVariableValue()), new ManaCostsImpl("{X}{G}{G}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new AddCountersTargetEffect( + CounterType.P1P1.createInstance(0), + new ManacostVariableValue() + ).setText("Put X +1/+1 counters on target land you control."), + new ManaCostsImpl("{X}{G}{G}") + ); Effect effect = new BecomesCreatureTargetEffect(new WallOfResurgenceToken(), false, true, Duration.Custom); effect.setText("That land becomes a 0/0 Elemental creature with haste. It's still a land"); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java b/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java index 2317a14d4e..f8abdd8272 100644 --- a/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java +++ b/Mage.Sets/src/mage/cards/w/WaterspoutElemental.java @@ -69,7 +69,7 @@ public class WaterspoutElemental extends CardImpl { EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandFromBattlefieldAllEffect(filter)); ability.addEffect(new SkipNextTurnSourceEffect()); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.instance, - "When {this} enters the battlefield, if it was kicked, return all other creatures to their owners' hands and you skip your next turn")); + "When {this} enters the battlefield, if it was kicked, return all other creatures to their owners' hands and you skip your next turn.")); } public WaterspoutElemental(final WaterspoutElemental card) { diff --git a/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java b/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java index 0e00876367..409af297ef 100644 --- a/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java +++ b/Mage/src/main/java/mage/abilities/common/CantBlockAbility.java @@ -47,7 +47,7 @@ public class CantBlockAbility extends SimpleStaticAbility { @Override public String getRule() { - return "{this} can't block"; + return "{this} can't block."; } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java b/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java index 72856c0629..f71ad50471 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/RaidCondition.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.condition.common; import mage.abilities.Ability; @@ -45,4 +44,8 @@ public enum RaidCondition implements Condition { PlayerAttackedWatcher watcher = (PlayerAttackedWatcher) game.getState().getWatchers().get(PlayerAttackedWatcher.class.getSimpleName()); return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) > 0; } + + public String toString() { + return "if you attacked with a creature this turn"; + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java index ad1aca5584..f1b8a2238f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java @@ -80,7 +80,6 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect StringBuilder sb = new StringBuilder(); sb.append("{this} can't be regenerated"); if (!duration.toString().isEmpty()) { - sb.append(' '); if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java index 4b53c47eaf..42bd8e092f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java @@ -243,7 +243,7 @@ public class LookLibraryControllerEffect extends OneShotEffect { sb.append(" cards "); } - sb.append("of your Library"); + sb.append("of your library"); if (numberLook == 0) { sb.append(", where {X} is the number of cards ").append(numberOfCards.getMessage()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java index cee08029fb..13948eef4d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAllPermanentsEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -98,10 +99,19 @@ public class PreventAllDamageByAllPermanentsEffect extends PreventionEffectImpl sb.append("combat "); } sb.append("damage "); - sb.append(duration.toString()); - if (filter != null) { - sb.append(" dealt by "); - sb.append(filter.getMessage()); + if (duration == EndOfTurn) { + if (filter != null) { + sb.append(filter.getMessage()); + sb.append(" would deal this turn"); + } else { + sb.append("that would be dealt this turn"); + } + } else { + sb.append(duration.toString()); + if (filter != null) { + sb.append(" dealt by "); + sb.append(filter.getMessage()); + } } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java index e4a0e40806..c1f0ade074 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.game.Game; import mage.game.events.GameEvent; @@ -74,7 +75,12 @@ public class PreventDamageToSourceEffect extends PreventionEffectImpl { } else { sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to "); } - sb.append("{source} ").append(duration.toString()); + sb.append("{source} "); + if (duration == EndOfTurn) { + sb.append("this turn"); + } else { + sb.append(duration.toString()); + } return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java index 0ad564a721..cca02db55a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import java.util.List; @@ -60,10 +59,10 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(targetPointer.getFirst(game, source)); - if(player != null) { + if (player != null) { filter.add(new ControllerIdPredicate(player.getId())); List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); - for(Permanent p : permanents) { + for (Permanent p : permanents) { p.tap(game); } return true; @@ -78,9 +77,9 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { @Override public String getText(Mode mode) { - if(staticText != null && !staticText.isEmpty()) { + if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "tap all " + filter.getMessage() + " target player controls"; + return "tap all " + filter.getMessage() + " target " + mode.getTargets().get(0).getMessage() + " controls"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index 76a23da819..1283cc5972 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; import mage.constants.AttachmentType; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -61,7 +62,9 @@ public class CantBlockAttachedEffect extends RestrictionEffect { if (!filter.getMessage().equals("creature")) { sb.append(' ').append(filter.getMessage()); } - if (!duration.toString().isEmpty()) { + if (duration == EndOfTurn) { + sb.append("this turn"); + } else if (!duration.toString().isEmpty()) { sb.append(' ').append(duration.toString()); } staticText = sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java index d97d8f9ea9..dde5970a68 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesChosenCreatureTypeTargetEffect.java @@ -26,7 +26,7 @@ public class BecomesChosenCreatureTypeTargetEffect extends OneShotEffect { super(Outcome.BoostCreature); this.nonWall = nonWall; if(nonWall) { - staticText = "choose a creature type other than wall. Target creature becomes that type until end of turn"; + staticText = "choose a creature type other than Wall. Target creature becomes that type until end of turn"; } else { staticText = "target creature becomes the creature type of your choice until end of turn"; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java index f6f796c25f..d78d9a26ef 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureAllEffect.java @@ -138,7 +138,6 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { if (duration.toString() != null && !duration.toString().isEmpty()) { sb.append(duration.toString()).append(", "); } - sb.append("all "); sb.append(filter.getMessage()); if (duration.toString() != null && duration.toString().isEmpty()) { sb.append(" are "); @@ -147,7 +146,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl { } sb.append(token.getDescription()); if (type != null && !type.isEmpty()) { - sb.append(". They are still ").append(type); + sb.append(". They're still ").append(type); } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java index 59ea028475..4fb3d05810 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java @@ -53,7 +53,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.ability = ability; this.filter = filter; - staticText = filter.getMessage() + " you cast have " + ability.getRule(); + staticText = filter.getMessage() + " you cast have " + ability.getRule() + '.'; } public GainAbilityControlledSpellsEffect(final GainAbilityControlledSpellsEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java index 3bc9ba0e98..b896c2b950 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersAllEffect.java @@ -36,6 +36,7 @@ import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.util.CardUtil; /** * @@ -82,7 +83,7 @@ public class AddCountersAllEffect extends OneShotEffect { StringBuilder sb = new StringBuilder(); sb.append("put "); if (counter.getCount() > 1) { - sb.append(Integer.toString(counter.getCount())).append(' ').append(counter.getName().toLowerCase()).append(" counters on each "); + sb.append(CardUtil.numberToText(counter.getCount(), "a")).append(' ').append(counter.getName().toLowerCase()).append(" counters on each "); } else { sb.append("a ").append(counter.getName().toLowerCase()).append(" counter on each "); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java index f540608e80..137a384bf1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java @@ -57,7 +57,7 @@ public class SearchLibraryGraveyardPutInHandEffect extends OneShotEffect { super(Outcome.Benefit); this.filter = filter; this.forceToSearchBoth = forceToSearchBoth; - staticText = "search your library and" + (forceToSearchBoth ? "" : "/or ") + " graveyard for a card named " + filter.getMessage() + staticText = "search your library and" + (forceToSearchBoth ? "" : "/or") + " graveyard for a card named " + filter.getMessage() + ", reveal it, and put it into your hand. " + (forceToSearchBoth ? "Then shuffle your library" : "If you search your library this way, shuffle it"); } diff --git a/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java b/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java index 514a4e3370..b746561a41 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DeathtouchAbility.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class DeathtouchAbility extends StaticAbility implements MageSingleton { - private static final DeathtouchAbility instance = new DeathtouchAbility(); + private static final DeathtouchAbility instance = new DeathtouchAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class DeathtouchAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Deathtouch (Any amount of damage this deals to a creature is enough to destroy it.)"; + return "deathtouch"; } @Override @@ -64,6 +63,4 @@ public class DeathtouchAbility extends StaticAbility implements MageSingleton { return instance; } - - } diff --git a/Mage/src/main/java/mage/abilities/keyword/FearAbility.java b/Mage/src/main/java/mage/abilities/keyword/FearAbility.java index e730552c9d..939b05cfab 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FearAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FearAbility.java @@ -24,11 +24,9 @@ * 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.abilities.keyword; -import mage.constants.CardType; import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.EvasionAbility; @@ -45,7 +43,7 @@ import java.io.ObjectStreamException; */ public class FearAbility extends EvasionAbility implements MageSingleton { - private static final FearAbility instance = new FearAbility(); + private static final FearAbility instance = new FearAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -61,7 +59,7 @@ public class FearAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Fear"; + return "fear"; } @Override @@ -102,4 +100,4 @@ class FearEffect extends RestrictionEffect implements MageSingleton { return new FearEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java b/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java index d5a09f1629..70d7008032 100644 --- a/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/IndestructibleAbility.java @@ -32,15 +32,15 @@ import mage.constants.Zone; import mage.abilities.StaticAbility; /** - * OLD RULES: - * 700.4. If a permanent is indestructible, rules and effects can't destroy it. (See rule 701.6, "Destroy.") - * Such permanents are not destroyed by lethal damage, and they ignore the lethal-damage state-based action - * (see rule 704.5g). Rules or effects may cause an indestructible permanent to be sacrificed, put into a - * graveyard, or exiled. # + * OLD RULES: 700.4. If a permanent is indestructible, rules and effects can't + * destroy it. (See rule 701.6, "Destroy.") Such permanents are not destroyed by + * lethal damage, and they ignore the lethal-damage state-based action (see rule + * 704.5g). Rules or effects may cause an indestructible permanent to be + * sacrificed, put into a graveyard, or exiled. # * - * 700.4a Although the text "[This permanent] is indestructible" is an ability, actually being - * indestructible is neither an ability nor a characteristic. It's just something that's true - * about a permanent. + * 700.4a Although the text "[This permanent] is indestructible" is an ability, + * actually being indestructible is neither an ability nor a characteristic. + * It's just something that's true about a permanent. * * NEW RULES * @@ -48,10 +48,9 @@ import mage.abilities.StaticAbility; * * * - * + * * @author BetaSteward_at_googlemail.com */ - public class IndestructibleAbility extends StaticAbility { private static final IndestructibleAbility instance; @@ -79,7 +78,7 @@ public class IndestructibleAbility extends StaticAbility { @Override public String getRule() { - return "Indestructible"; + return "indestructible"; } } From 14107b3d55b81477384ca8750f15a11e5fa1dcd4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 11:02:36 -0400 Subject: [PATCH 67/68] 2 text 2 fixrious --- .../src/mage/cards/a/AlliedStrategies.java | 5 +- .../src/mage/cards/a/AtalyaSamiteMaster.java | 4 +- .../src/mage/cards/a/AuramancersGuise.java | 2 +- .../src/mage/cards/b/BlackManaBattery.java | 3 +- .../src/mage/cards/b/BlueManaBattery.java | 2 +- .../src/mage/cards/b/BraidsConjurerAdept.java | 6 +- .../src/mage/cards/c/CollapsingBorders.java | 4 +- .../src/mage/cards/c/CollectiveRestraint.java | 5 +- Mage.Sets/src/mage/cards/c/Confound.java | 4 +- Mage.Sets/src/mage/cards/d/Detritivore.java | 5 +- Mage.Sets/src/mage/cards/e/EnergyTap.java | 8 +-- Mage.Sets/src/mage/cards/e/EvasiveAction.java | 4 +- Mage.Sets/src/mage/cards/e/ExoticCurse.java | 9 ++- Mage.Sets/src/mage/cards/f/FatalFrenzy.java | 10 ++- .../src/mage/cards/f/FirebrandRanger.java | 8 +-- Mage.Sets/src/mage/cards/g/GateSmasher.java | 4 +- Mage.Sets/src/mage/cards/g/GhituFire.java | 5 +- .../src/mage/cards/g/GleamOfAuthority.java | 19 +++--- Mage.Sets/src/mage/cards/g/GohamDjinn.java | 5 ++ .../src/mage/cards/g/GreaterStoneSpirit.java | 12 ++-- .../src/mage/cards/g/GreenManaBattery.java | 2 +- .../src/mage/cards/h/HedonistsTrove.java | 4 +- .../src/mage/cards/h/HerdchaserDragon.java | 12 ++-- Mage.Sets/src/mage/cards/i/IllusoryGains.java | 4 +- .../src/mage/cards/k/KangeeAerieKeeper.java | 18 +++--- Mage.Sets/src/mage/cards/k/KavuScout.java | 8 ++- Mage.Sets/src/mage/cards/k/KrovikanMist.java | 14 ++-- Mage.Sets/src/mage/cards/l/LoseCalm.java | 6 +- .../mage/cards/m/MagusOfTheTabernacle.java | 2 +- Mage.Sets/src/mage/cards/m/MidnightCharm.java | 4 +- Mage.Sets/src/mage/cards/m/MirrorMockery.java | 4 +- Mage.Sets/src/mage/cards/n/NullProfusion.java | 31 +++++---- .../src/mage/cards/o/OjutaiExemplars.java | 14 ++-- .../src/mage/cards/o/OrderedMigration.java | 2 + Mage.Sets/src/mage/cards/o/Overload.java | 64 ++++++++++++------- Mage.Sets/src/mage/cards/o/Ovinize.java | 9 ++- .../src/mage/cards/p/PoulticeSliver.java | 2 +- Mage.Sets/src/mage/cards/p/PowerArmor.java | 4 +- .../src/mage/cards/p/PrisonBarricade.java | 14 ++-- Mage.Sets/src/mage/cards/p/Probe.java | 12 ++-- Mage.Sets/src/mage/cards/p/Prohibit.java | 64 +++++++++++-------- Mage.Sets/src/mage/cards/p/PyreZombie.java | 6 +- .../src/mage/cards/q/QuicksilverDagger.java | 11 ++-- .../src/mage/cards/q/QuirionTrailblazer.java | 5 +- .../src/mage/cards/r/RedManaBattery.java | 2 +- .../src/mage/cards/r/RewardsOfDiversity.java | 4 +- .../src/mage/cards/r/RisenExecutioner.java | 30 ++++----- Mage.Sets/src/mage/cards/r/RoilingHorror.java | 8 ++- .../src/mage/cards/s/SaprolingSymbiosis.java | 5 +- .../src/mage/cards/s/SarkhanUnbroken.java | 2 +- Mage.Sets/src/mage/cards/s/SawtoothLoon.java | 4 +- Mage.Sets/src/mage/cards/s/ScaleBlessing.java | 2 +- .../src/mage/cards/s/ScaleguardSentinels.java | 4 +- Mage.Sets/src/mage/cards/s/ScorchingLava.java | 5 +- Mage.Sets/src/mage/cards/s/SeersVision.java | 4 +- .../src/mage/cards/s/ServantOfTheScale.java | 10 +-- .../src/mage/cards/s/ShieldhideDragon.java | 12 ++-- .../mage/cards/s/SightOfTheScalelords.java | 6 +- Mage.Sets/src/mage/cards/s/StormriderRig.java | 14 ++-- .../src/mage/cards/s/StormscapeMaster.java | 6 +- .../src/mage/cards/s/StormwingDragon.java | 12 ++-- .../src/mage/cards/s/SulfurElemental.java | 13 ++-- .../src/mage/cards/t/TemporalDistortion.java | 2 +- .../src/mage/cards/t/ThunderscapeMaster.java | 4 +- .../src/mage/cards/u/UrborgSkeleton.java | 14 ++-- .../src/mage/cards/v/VodalianMerchant.java | 6 +- .../src/mage/cards/w/WhiteManaBattery.java | 2 +- Mage/src/main/java/mage/Mana.java | 18 +++--- ...yMoreToCastAsThoughtItHadFlashAbility.java | 2 +- .../common/CardsInHandCondition.java | 3 +- .../AddConditionalManaOfAnyColorEffect.java | 7 +- .../common/CastSourceTriggeredAbility.java | 7 +- .../common/CounterUnlessPaysEffect.java | 2 +- .../effects/common/GetEmblemEffect.java | 20 +++++- .../effects/common/NameACardEffect.java | 17 ++--- .../common/UntapAllThatAttackedEffect.java | 2 +- .../CantBeBlockedByAllTargetEffect.java | 4 +- .../continuous/BoostEnchantedEffect.java | 2 +- .../search/SearchLibraryPutInPlayEffect.java | 5 +- .../effects/keyword/BolsterEffect.java | 2 +- .../mage/abilities/keyword/DashAbility.java | 1 + .../mage/abilities/keyword/ReachAbility.java | 7 +- .../abilities/keyword/SuspendAbility.java | 2 +- 83 files changed, 412 insertions(+), 300 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java index 7d1009bad9..517210b49b 100644 --- a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java +++ b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.target.TargetPlayer; @@ -42,11 +43,13 @@ import mage.target.TargetPlayer; public class AlliedStrategies extends CardImpl { public AlliedStrategies(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}"); // Domain - Target player draws a card for each basic land type among lands he or she controls. this.getSpellAbility().addEffect(new DrawCardTargetEffect(new DomainValue(true))); this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); + } public AlliedStrategies(final AlliedStrategies card) { diff --git a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java index 474945b89a..8a62d61886 100644 --- a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java +++ b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java @@ -68,7 +68,7 @@ public class AtalyaSamiteMaster extends CardImpl { // {X}, {tap}: Choose one - Prevent the next X damage that would be dealt to target creature this turn; or you gain X life. Spend only white mana on X. PreventDamageToTargetEffect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue()); - effect.setText("Prevent the next X damage that would be dealt to target creature this turn"); + effect.setText("Prevent the next X damage that would be dealt to target creature this turn. Spend only white mana on X."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); ability.addCost(new TapSourceCost()); @@ -81,7 +81,7 @@ public class AtalyaSamiteMaster extends CardImpl { // or you gain X life Mode mode = new Mode(); - mode.getEffects().add(new GainLifeEffect(new ManacostVariableValue())); + mode.getEffects().add(new GainLifeEffect(new ManacostVariableValue()).setText("You gain X life. Spend only white mana on X.")); ability.addMode(mode); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/AuramancersGuise.java b/Mage.Sets/src/mage/cards/a/AuramancersGuise.java index 7ccaf66d28..7bb76dcc1f 100644 --- a/Mage.Sets/src/mage/cards/a/AuramancersGuise.java +++ b/Mage.Sets/src/mage/cards/a/AuramancersGuise.java @@ -70,7 +70,7 @@ public class AuramancersGuise extends CardImpl { BoostEnchantedEffect effect = new BoostEnchantedEffect(ptBoost, ptBoost, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +2/+2 for each Aura attached to it"); SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); - ability2.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); + ability2.addEffect(new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA).setText("and has vigilance")); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java index 8e6449f4d1..412775a234 100644 --- a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java @@ -53,7 +53,6 @@ public class BlackManaBattery extends CardImpl { public BlackManaBattery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); - // {2}, {tap}: Put a charge counter on Black Mana Battery. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance(1)), new GenericManaCost(2)); @@ -68,7 +67,7 @@ public class BlackManaBattery extends CardImpl { "Add {B} to your mana pool, then add {B} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java index 410b81cb00..6883996517 100644 --- a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java @@ -67,7 +67,7 @@ public class BlueManaBattery extends CardImpl { "Add {U} to your mana pool, then add {U} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java index 950894450f..0f1050c875 100644 --- a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java +++ b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java @@ -47,8 +47,8 @@ import mage.filter.predicate.mageobject.CardTypePredicate; */ public class BraidsConjurerAdept extends CardImpl { - private static final FilterCard filter = new FilterCard("artifact, creature, or land card") -; + private static final FilterCard filter = new FilterCard("an artifact, creature, or land card"); + static { filter.add(Predicates.or( new CardTypePredicate(CardType.ARTIFACT), @@ -57,7 +57,7 @@ public class BraidsConjurerAdept extends CardImpl { } public BraidsConjurerAdept(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN, SubType.WIZARD); this.power = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java index b99b7dfd7f..c273b3e7b8 100644 --- a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java +++ b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java @@ -36,6 +36,7 @@ import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.TargetController; @@ -47,7 +48,7 @@ import mage.constants.TargetController; public class CollapsingBorders extends CardImpl { public CollapsingBorders(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); // Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands he or she controls. Then Collapsing Borders deals 3 damage to him or her. Effect effect = new GainLifeTargetEffect(new DomainValue(true)); @@ -56,6 +57,7 @@ public class CollapsingBorders extends CardImpl { effect = new DamageTargetEffect(3); effect.setText("Then {this} deals 3 damage to him or her."); ability.addEffect(effect); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java index a956c84595..d2b60309a0 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java @@ -36,6 +36,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.combat.CantAttackYouUnlessPayManaAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Zone; import mage.game.Game; @@ -51,7 +52,9 @@ public class CollectiveRestraint extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); // Domain - Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types you control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CollectiveRestraintPayManaToAttackAllEffect())); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new CollectiveRestraintPayManaToAttackAllEffect()); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/Confound.java b/Mage.Sets/src/mage/cards/c/Confound.java index 38575e88dc..3675f891f2 100644 --- a/Mage.Sets/src/mage/cards/c/Confound.java +++ b/Mage.Sets/src/mage/cards/c/Confound.java @@ -44,14 +44,14 @@ import mage.target.TargetSpell; */ public class Confound extends CardImpl { - private final static FilterSpell filter = new FilterSpell("spell that targets one or more creatures"); + private final static FilterSpell filter = new FilterSpell("spell that targets a creature"); static { filter.add(new TargetsPermanentPredicate(new FilterCreaturePermanent())); } public Confound(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Counter target spell that targets one or more creatures. this.getSpellAbility().addEffect(new CounterTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/d/Detritivore.java b/Mage.Sets/src/mage/cards/d/Detritivore.java index 4be1d1f684..1865dfd752 100644 --- a/Mage.Sets/src/mage/cards/d/Detritivore.java +++ b/Mage.Sets/src/mage/cards/d/Detritivore.java @@ -63,7 +63,7 @@ import mage.target.common.TargetNonBasicLandPermanent; public class Detritivore extends CardImpl { public Detritivore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.LHURGOYF); this.power = new MageInt(0); @@ -132,7 +132,6 @@ class NonBasicLandsInOpponentsGraveyards implements DynamicValue { filter.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); } - @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { int amount = 0; @@ -162,6 +161,6 @@ class NonBasicLandsInOpponentsGraveyards implements DynamicValue { @Override public String getMessage() { - return "the number of nonbasic land cards in your opponents' graveyards"; + return "nonbasic land cards in your opponents' graveyards"; } } diff --git a/Mage.Sets/src/mage/cards/e/EnergyTap.java b/Mage.Sets/src/mage/cards/e/EnergyTap.java index 2eab464759..3012505d16 100644 --- a/Mage.Sets/src/mage/cards/e/EnergyTap.java +++ b/Mage.Sets/src/mage/cards/e/EnergyTap.java @@ -56,9 +56,9 @@ public class EnergyTap extends CardImpl { } public EnergyTap(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}"); - // Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost. + // Tap target untapped creature you control. If you do, add an amount of {C} to your mana pool equal to that creature's converted mana cost. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(filter)); this.getSpellAbility().addEffect(new EnergyTapEffect()); } @@ -77,7 +77,7 @@ class EnergyTapEffect extends OneShotEffect { EnergyTapEffect() { super(Outcome.PutManaInPool); - this.staticText = "Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost"; + this.staticText = "Tap target untapped creature you control. If you do, add an amount of {C} to your mana pool equal to that creature's converted mana cost"; } EnergyTapEffect(final EnergyTapEffect effect) { @@ -106,4 +106,4 @@ class EnergyTapEffect extends OneShotEffect { } return applied; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/e/EvasiveAction.java b/Mage.Sets/src/mage/cards/e/EvasiveAction.java index f271c86d6d..87773fdc23 100644 --- a/Mage.Sets/src/mage/cards/e/EvasiveAction.java +++ b/Mage.Sets/src/mage/cards/e/EvasiveAction.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.target.TargetSpell; @@ -42,11 +43,12 @@ import mage.target.TargetSpell; public class EvasiveAction extends CardImpl { public EvasiveAction(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Domain - Counter target spell unless its controller pays {1} for each basic land type among lands you control. this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new DomainValue())); this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public EvasiveAction(final EvasiveAction card) { diff --git a/Mage.Sets/src/mage/cards/e/ExoticCurse.java b/Mage.Sets/src/mage/cards/e/ExoticCurse.java index f1adf3fee9..34c231b9bb 100644 --- a/Mage.Sets/src/mage/cards/e/ExoticCurse.java +++ b/Mage.Sets/src/mage/cards/e/ExoticCurse.java @@ -28,6 +28,7 @@ package mage.cards.e; import java.util.UUID; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.DomainValue; @@ -37,6 +38,7 @@ import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -51,7 +53,7 @@ import mage.target.TargetPermanent; public class ExoticCurse extends CardImpl { public ExoticCurse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -62,8 +64,9 @@ public class ExoticCurse extends CardImpl { // Domain - Enchanted creature gets -1/-1 for each basic land type among lands you control. DynamicValue unboost = new SignInversionDynamicValue(new DomainValue()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new BoostEnchantedEffect(unboost, unboost, Duration.WhileOnBattlefield))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(unboost, unboost, Duration.WhileOnBattlefield)); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public ExoticCurse(final ExoticCurse card) { diff --git a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java index 08ab764a29..2794d52a20 100644 --- a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java +++ b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java @@ -55,11 +55,15 @@ import mage.target.targetpointer.FixedTarget; public class FatalFrenzy extends CardImpl { public FatalFrenzy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // Until end of turn, target creature you control gains trample and gets +X/+0, where X is its power. Sacrifice it at the beginning of the next end step. - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) + .setText("Until end of turn, target creature you control gains trample") + ); + this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true) + .setText("and gets +X/+0, where X is its power.") + ); this.getSpellAbility().addEffect(new FatalFrenzyEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java index 4ea4f8bcf6..3c335a7fd5 100644 --- a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java +++ b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCardInHand; public class FirebrandRanger extends CardImpl { public FirebrandRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); @@ -80,7 +80,7 @@ public class FirebrandRanger extends CardImpl { } class PutLandOnBattlefieldEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("basic land card"); static { @@ -91,7 +91,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { public PutLandOnBattlefieldEffect() { super(Outcome.PutLandInPlay); - this.staticText = "put a basic land card from your hand onto the battlefield"; + this.staticText = "you may put a basic land card from your hand onto the battlefield"; } public PutLandOnBattlefieldEffect(final PutLandOnBattlefieldEffect effect) { @@ -120,4 +120,4 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GateSmasher.java b/Mage.Sets/src/mage/cards/g/GateSmasher.java index 4b16473ea6..f8b0b896bc 100644 --- a/Mage.Sets/src/mage/cards/g/GateSmasher.java +++ b/Mage.Sets/src/mage/cards/g/GateSmasher.java @@ -56,14 +56,14 @@ import mage.target.common.TargetControlledCreaturePermanent; */ public class GateSmasher extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with 3 or more power"); + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with toughness 4 or greater"); static { filter.add(new ToughnessPredicate(ComparisonType.MORE_THAN, 3)); } public GateSmasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); Target target = new TargetControlledCreaturePermanent(1, 1, filter, false); diff --git a/Mage.Sets/src/mage/cards/g/GhituFire.java b/Mage.Sets/src/mage/cards/g/GhituFire.java index ff3fe2b8fe..833cf73397 100644 --- a/Mage.Sets/src/mage/cards/g/GhituFire.java +++ b/Mage.Sets/src/mage/cards/g/GhituFire.java @@ -42,18 +42,19 @@ import mage.target.common.TargetCreatureOrPlayer; /** * * @author LoneFox - + * */ public class GhituFire extends CardImpl { public GhituFire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}"); Effect effect = new DamageTargetEffect(new ManacostVariableValue()); // You may cast Ghitu Fire as though it had flash if you pay {2} more to cast it. Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl("{2}")); ability.addEffect(effect); ability.addTarget(new TargetCreatureOrPlayer()); + ability.setRuleAtTheTop(true); this.addAbility(ability); // Ghitu Fire deals X damage to target creature or player. this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java index 75f1d0d912..82f91c5ec9 100644 --- a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java +++ b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCreaturePermanent; public class GleamOfAuthority extends CardImpl { public GleamOfAuthority(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -67,16 +67,17 @@ public class GleamOfAuthority extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control DynamicValue amount = new CountersOnControlledCount(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); + // Enchanted creature has vigilance and "{W}, {T}: Bloster 1." - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA))); - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BolsterEffect(1), new ManaCostsImpl("{W}")); - ability.addCost(new TapSourceCost()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BolsterEffect(1), new ManaCostsImpl("{W}")); + gainedAbility.addCost(new TapSourceCost()); + ability.addEffect(new GainAbilityAttachedEffect(ability, AttachmentType.AURA).setText("and \"{W}, {T}: Bloster 1.\"")); + this.addAbility(ability); } public GleamOfAuthority(final GleamOfAuthority card) { @@ -92,7 +93,7 @@ public class GleamOfAuthority extends CardImpl { class CountersOnControlledCount implements DynamicValue { static FilterCreaturePermanent filter = new FilterCreaturePermanent(); - + public CountersOnControlledCount() { } diff --git a/Mage.Sets/src/mage/cards/g/GohamDjinn.java b/Mage.Sets/src/mage/cards/g/GohamDjinn.java index 5267094237..412d5d98d8 100644 --- a/Mage.Sets/src/mage/cards/g/GohamDjinn.java +++ b/Mage.Sets/src/mage/cards/g/GohamDjinn.java @@ -30,9 +30,12 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.ObjectColor; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.MostCommonColorCondition; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.RegenerateSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -55,6 +58,8 @@ public class GohamDjinn extends CardImpl { this.toughness = new MageInt(5); // {1}{B}: Regenerate Goham Djinn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{B}"))); + // Goham Djinn gets -2/-2 as long as black is the most common color among all permanents or is tied for most common. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(-2, -2, Duration.WhileOnBattlefield), diff --git a/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java b/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java index 1f3702f52a..a9a59aefb1 100644 --- a/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java +++ b/Mage.Sets/src/mage/cards/g/GreaterStoneSpirit.java @@ -54,14 +54,15 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class GreaterStoneSpirit extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying"); + static { filter.add(new AbilityPredicate(FlyingAbility.class)); } public GreaterStoneSpirit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(4); @@ -69,10 +70,13 @@ public class GreaterStoneSpirit extends CardImpl { // Greater Stone Spirit can't be blocked by creatures with flying. this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); - + // {2}{R}: Until end of turn, target creature gets +0/+2 and gains "{R}: This creature gets +1/+0 until end of turn." Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")); + new BoostSourceEffect(1, 0, Duration.EndOfTurn) + .setText("until end of turn, target creature gets +0/+2"), + new ManaCostsImpl("{R}") + ); Effect effect = new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn); effect.setText("and gains \"{R}: This creature gets +1/+0 until end of turn.\""); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(0, 2, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}")); diff --git a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java index 7a407edcc5..0e273c06e0 100644 --- a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java +++ b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java @@ -67,7 +67,7 @@ public class GreenManaBattery extends CardImpl { "Add {G} to your mana pool, then add {G} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java index a024d4458a..44aa5b482b 100644 --- a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java +++ b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java @@ -54,7 +54,7 @@ import java.util.UUID; public class HedonistsTrove extends CardImpl { public HedonistsTrove(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{B}{B}"); // When Hedonist's Trove enters the battlefield, exile all cards from target opponent's graveyard. Ability ability = new EntersBattlefieldTriggeredAbility(new HedonistsTroveExileEffect()); @@ -115,7 +115,7 @@ class HedonistsTrovePlayLandEffect extends AsThoughEffectImpl { public HedonistsTrovePlayLandEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "You may play land cards exiled by {this}"; + staticText = "You may play land cards exiled with {this}"; } public HedonistsTrovePlayLandEffect(final HedonistsTrovePlayLandEffect effect) { diff --git a/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java b/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java index 5e3579d710..a5c7b8ceda 100644 --- a/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java +++ b/Mage.Sets/src/mage/cards/h/HerdchaserDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class HerdchaserDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class HerdchaserDragon extends CardImpl { } public HerdchaserDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // Trample this.addAbility(TrampleAbility.getInstance()); - + // Megamorph {5}{G}{G} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{G}{G}"), true)); - + // When Herdchaser Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/i/IllusoryGains.java b/Mage.Sets/src/mage/cards/i/IllusoryGains.java index 74c227de3b..d2b7f01df0 100644 --- a/Mage.Sets/src/mage/cards/i/IllusoryGains.java +++ b/Mage.Sets/src/mage/cards/i/IllusoryGains.java @@ -65,7 +65,7 @@ public class IllusoryGains extends CardImpl { } public IllusoryGains(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -80,7 +80,7 @@ public class IllusoryGains extends CardImpl { // Whenever a creature enters the battlefield under an opponent's control, attach Illusory Gains to that creature. this.addAbility(new EntersBattlefieldAllTriggeredAbility( - Zone.BATTLEFIELD, new IllusoryGainsEffect(), filter, false, SetTargetPointer.PERMANENT, "Whenever a creature enters the battlefield under an opponent's control, you attach Illusory Gains to that creature.")); + Zone.BATTLEFIELD, new IllusoryGainsEffect(), filter, false, SetTargetPointer.PERMANENT, "Whenever a creature enters the battlefield under an opponent's control, attach Illusory Gains to that creature.")); } public IllusoryGains(final IllusoryGains card) { diff --git a/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java b/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java index 7dea607f9c..6c2bf15440 100644 --- a/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java +++ b/Mage.Sets/src/mage/cards/k/KangeeAerieKeeper.java @@ -57,16 +57,16 @@ import mage.game.Game; * @author emerald000 */ public class KangeeAerieKeeper extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Bird creatures"); - + static { filter.add(new SubtypePredicate(SubType.BIRD)); filter.add(new AnotherPredicate()); } public KangeeAerieKeeper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.BIRD); this.subtype.add(SubType.WIZARD); @@ -75,15 +75,15 @@ public class KangeeAerieKeeper extends CardImpl { this.toughness = new MageInt(2); // Kicker {X}{2} - this.addAbility(new KickerAbility("{X}{2}")); - + this.addAbility(new KickerAbility("{2}{X}")); + // Flying this.addAbility(FlyingAbility.getInstance()); - + // When Kangee, Aerie Keeper enters the battlefield, if it was kicked, put X feather counters on it. TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.FEATHER.createInstance(), new KangeeAerieKeeperGetKickerXValue(), true)); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.instance, "When {this} enters the battlefield, if it was kicked, put X feather counters on it.")); - + // Other Bird creatures get +1/+1 for each feather counter on Kangee, Aerie Keeper. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(new CountersSourceCount(CounterType.FEATHER), new CountersSourceCount(CounterType.FEATHER), Duration.WhileOnBattlefield, filter, true, "Other Bird creatures get +1/+1 for each feather counter on {this}."))); } @@ -108,7 +108,7 @@ class KangeeAerieKeeperGetKickerXValue implements DynamicValue { int count = 0; Card card = game.getCard(source.getSourceId()); if (card != null) { - for (Ability ability: card.getAbilities()) { + for (Ability ability : card.getAbilities()) { if (ability instanceof KickerAbility) { count += ((KickerAbility) ability).getXManaValue(); } @@ -131,4 +131,4 @@ class KangeeAerieKeeperGetKickerXValue implements DynamicValue { public String getMessage() { return "X"; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/k/KavuScout.java b/Mage.Sets/src/mage/cards/k/KavuScout.java index f8bcb743a3..f9a94eadcc 100644 --- a/Mage.Sets/src/mage/cards/k/KavuScout.java +++ b/Mage.Sets/src/mage/cards/k/KavuScout.java @@ -29,12 +29,14 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -47,7 +49,7 @@ import mage.constants.Zone; public class KavuScout extends CardImpl { public KavuScout(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.KAVU); this.subtype.add(SubType.SCOUT); @@ -55,7 +57,9 @@ public class KavuScout extends CardImpl { this.toughness = new MageInt(2); // Domain - Kavu Scout gets +1/+0 for each basic land type among lands you control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new DomainValue(), new StaticValue(0), Duration.WhileOnBattlefield))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new DomainValue(), new StaticValue(0), Duration.WhileOnBattlefield)); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public KavuScout(final KavuScout card) { diff --git a/Mage.Sets/src/mage/cards/k/KrovikanMist.java b/Mage.Sets/src/mage/cards/k/KrovikanMist.java index 3cd681609c..e937c2d8db 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanMist.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanMist.java @@ -39,7 +39,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; /** @@ -47,15 +47,15 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author LevelX2 */ public class KrovikanMist extends CardImpl { - - private static final FilterControlledPermanent controlledIllusionsFilter = new FilterControlledPermanent("Illusions you control"); - + + private static final FilterPermanent illusionsFilter = new FilterPermanent("Illusions on the battlefield"); + static { - controlledIllusionsFilter.add(new SubtypePredicate(SubType.ILLUSION)); + illusionsFilter.add(new SubtypePredicate(SubType.ILLUSION)); } public KrovikanMist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.ILLUSION); this.power = new MageInt(0); @@ -65,7 +65,7 @@ public class KrovikanMist extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Krovikan Mist's power and toughness are each equal to the number of Illusions on the battlefield. this.addAbility(new SimpleStaticAbility(Zone.ALL, - new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(controlledIllusionsFilter), Duration.EndOfGame))); + new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(illusionsFilter), Duration.EndOfGame))); } diff --git a/Mage.Sets/src/mage/cards/l/LoseCalm.java b/Mage.Sets/src/mage/cards/l/LoseCalm.java index 7891c5c802..d64891833c 100644 --- a/Mage.Sets/src/mage/cards/l/LoseCalm.java +++ b/Mage.Sets/src/mage/cards/l/LoseCalm.java @@ -47,17 +47,17 @@ import mage.target.common.TargetCreaturePermanent; public class LoseCalm extends CardImpl { public LoseCalm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Gain control of target creature until end of turn. Untap that creature. It gains haste and menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); Effect effect = new UntapTargetEffect(); effect.setText("Untap that creature"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "It gains haste until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "It gains haste")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); effect = new GainAbilityTargetEffect(new MenaceAbility(), Duration.EndOfTurn); - effect.setText("and menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) "); + effect.setText("and menace until end of turn"); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java b/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java index a85772a723..0fdd344d1e 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheTabernacle.java @@ -50,7 +50,7 @@ import mage.filter.StaticFilters; */ public class MagusOfTheTabernacle extends CardImpl { - static private final String rule = "All creatures have \"At the beginning of your upkeep, sacrifice this creature unless you pay {1}\""; + static private final String rule = "All creatures have \"At the beginning of your upkeep, sacrifice this creature unless you pay {1}.\""; public MagusOfTheTabernacle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); diff --git a/Mage.Sets/src/mage/cards/m/MidnightCharm.java b/Mage.Sets/src/mage/cards/m/MidnightCharm.java index 10b4c3e693..f4e9be58d9 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightCharm.java +++ b/Mage.Sets/src/mage/cards/m/MidnightCharm.java @@ -47,11 +47,11 @@ import mage.target.common.TargetCreaturePermanent; public class MidnightCharm extends CardImpl { public MidnightCharm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Choose one - Midnight Charm deals 1 damage to target creature and you gain 1 life; or target creature gains first strike until end of turn; or tap target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(1)); - this.getSpellAbility().addEffect(new GainLifeEffect(1)); + this.getSpellAbility().addEffect(new GainLifeEffect(1).setText("and you gain 1 life")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); Mode mode = new Mode(); mode.getEffects().add(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/m/MirrorMockery.java b/Mage.Sets/src/mage/cards/m/MirrorMockery.java index f4c4534942..b0572190fb 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMockery.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMockery.java @@ -55,7 +55,7 @@ import mage.target.targetpointer.FixedTarget; public class MirrorMockery extends CardImpl { public MirrorMockery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -83,7 +83,7 @@ class MirrorMockeryEffect extends OneShotEffect { public MirrorMockeryEffect() { super(Outcome.Benefit); - this.staticText = "you may create a token that's a copy of that creature. Exile that token at the end of combat"; + this.staticText = "you may create a token that's a copy of that creature. Exile that token at end of combat"; } public MirrorMockeryEffect(final MirrorMockeryEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NullProfusion.java b/Mage.Sets/src/mage/cards/n/NullProfusion.java index acfa8a026a..d319c62a11 100644 --- a/Mage.Sets/src/mage/cards/n/NullProfusion.java +++ b/Mage.Sets/src/mage/cards/n/NullProfusion.java @@ -30,6 +30,7 @@ package mage.cards.n; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.SkipDrawStepEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; @@ -38,6 +39,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -50,16 +52,23 @@ import mage.game.events.GameEvent.EventType; public class NullProfusion extends CardImpl { public NullProfusion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}"); // Skip your draw step. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect())); + // Whenever you play a card, draw a card. this.addAbility(new NullProfusionTriggeredAbility()); - + // Your maximum hand size is two. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MaximumHandSizeControllerEffect(2, Duration.WhileOnBattlefield, HandSizeModification.SET))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new MaximumHandSizeControllerEffect( + new StaticValue(2), + Duration.WhileOnBattlefield, + HandSizeModification.SET, + TargetController.YOU + ) + )); } public NullProfusion(final NullProfusion card) { @@ -73,15 +82,15 @@ public class NullProfusion extends CardImpl { } class NullProfusionTriggeredAbility extends TriggeredAbilityImpl { - + NullProfusionTriggeredAbility() { super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); } - + NullProfusionTriggeredAbility(final NullProfusionTriggeredAbility ability) { super(ability); } - + @Override public NullProfusionTriggeredAbility copy() { return new NullProfusionTriggeredAbility(this); @@ -91,14 +100,14 @@ class NullProfusionTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == EventType.SPELL_CAST || event.getType() == EventType.LAND_PLAYED; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { return event.getPlayerId().equals(this.getControllerId()); } - + @Override public String getRule() { return "Whenever you play a card, draw a card."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java b/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java index 74717e6e7c..49a334ddfd 100644 --- a/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java +++ b/Mage.Sets/src/mage/cards/o/OjutaiExemplars.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class OjutaiExemplars extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("a noncreature spell"); static { @@ -66,7 +66,7 @@ public class OjutaiExemplars extends CardImpl { } public OjutaiExemplars(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.MONK); this.power = new MageInt(4); @@ -75,22 +75,22 @@ public class OjutaiExemplars extends CardImpl { // Whenever you cast a noncreature spell, choose one - Tap target creature; Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filter, false); ability.addTarget(new TargetCreaturePermanent()); - + // Ojutai Exemplars gain first strike and lifelink until end of turn; Mode mode = new Mode(); Effect effect = new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); effect.setText("{this} gains first strike"); mode.getEffects().add(effect); Effect effect2 = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); - effect2.setText("and lifelink"); + effect2.setText("and lifelink until end of turn"); mode.getEffects().add(effect2); ability.addMode(mode); - + // or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control. mode = new Mode(); mode.getEffects().add(new OjutaiExemplarsEffect()); ability.addMode(mode); - + this.addAbility(ability); } @@ -133,4 +133,4 @@ class OjutaiExemplarsEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OrderedMigration.java b/Mage.Sets/src/mage/cards/o/OrderedMigration.java index 179b6d6e62..ee18b8acf7 100644 --- a/Mage.Sets/src/mage/cards/o/OrderedMigration.java +++ b/Mage.Sets/src/mage/cards/o/OrderedMigration.java @@ -32,6 +32,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.CreateTokenEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.game.permanent.token.OrderedMigrationBirdToken; @@ -47,6 +48,7 @@ public class OrderedMigration extends CardImpl { // Domain - Create a 1/1 blue Bird creature token with flying for each basic land type among lands you control. this.getSpellAbility().addEffect(new CreateTokenEffect(new OrderedMigrationBirdToken(), new DomainValue())); + this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN); } public OrderedMigration(final OrderedMigration card) { diff --git a/Mage.Sets/src/mage/cards/o/Overload.java b/Mage.Sets/src/mage/cards/o/Overload.java index 3913a90d2e..6e956bb8f7 100644 --- a/Mage.Sets/src/mage/cards/o/Overload.java +++ b/Mage.Sets/src/mage/cards/o/Overload.java @@ -29,17 +29,17 @@ package mage.cards.o; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetArtifactPermanent; /** @@ -48,32 +48,15 @@ import mage.target.common.TargetArtifactPermanent; */ public class Overload extends CardImpl { - private static final FilterArtifactPermanent filter2 = new FilterArtifactPermanent("artifact if its converted mana cost is 2 or less"); - private static final FilterArtifactPermanent filter5 = new FilterArtifactPermanent("artifact if its converted mana cost is 5 or less"); - - static { - filter2.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); - filter5.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 5)); - } - public Overload(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); // Kicker {2} this.addAbility(new KickerAbility("{2}")); + // Destroy target artifact if its converted mana cost is 2 or less. If Overload was kicked, destroy that artifact if its converted mana cost is 5 or less instead. this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addTarget(new TargetArtifactPermanent(filter5)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { - if(!KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - ability.getTargets().add(new TargetArtifactPermanent(filter2)); - } - } + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); } public Overload(final Overload card) { @@ -85,3 +68,36 @@ public class Overload extends CardImpl { return new Overload(this); } } + +class OverloadEffect extends OneShotEffect { + + OverloadEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target artifact if its converted mana cost is 2 or less. If {this} was kicked, destroy that artifact if its converted mana cost is 5 or less instead."; + } + + OverloadEffect(final OverloadEffect effect) { + super(effect); + } + + @Override + public OverloadEffect copy() { + return new OverloadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent targetArtifact = game.getPermanent(this.getTargetPointer().getFirst(game, source)); + if (targetArtifact != null) { + int cmc = targetArtifact.getConvertedManaCost(); + if (cmc <= 2 || (KickedCondition.instance.apply(game, source) && cmc <= 5)) { + targetArtifact.destroy(source.getSourceId(), game, false); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/o/Ovinize.java b/Mage.Sets/src/mage/cards/o/Ovinize.java index a69bc20af0..6c9af1d7dc 100644 --- a/Mage.Sets/src/mage/cards/o/Ovinize.java +++ b/Mage.Sets/src/mage/cards/o/Ovinize.java @@ -40,16 +40,19 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class Ovinize extends CardImpl { public Ovinize(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Target creature loses all abilities and becomes 0/1 until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().addEffect( + new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) + .setText("Until end of turn, target creature loses all abilities") + ); Effect effect = new SetPowerToughnessTargetEffect(0, 1, Duration.EndOfTurn); effect.setText("and has base power and toughness 0/1"); this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/p/PoulticeSliver.java b/Mage.Sets/src/mage/cards/p/PoulticeSliver.java index 4d7cf354c9..079aab0ce4 100644 --- a/Mage.Sets/src/mage/cards/p/PoulticeSliver.java +++ b/Mage.Sets/src/mage/cards/p/PoulticeSliver.java @@ -66,7 +66,7 @@ public class PoulticeSliver extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, - "Slivers have \"{2}, {T}: Regenerate target Sliver.\""))); + "All Slivers have \"{2}, {T}: Regenerate target Sliver.\""))); } public PoulticeSliver(final PoulticeSliver card) { diff --git a/Mage.Sets/src/mage/cards/p/PowerArmor.java b/Mage.Sets/src/mage/cards/p/PowerArmor.java index 11fce7c8ca..ae96023b0f 100644 --- a/Mage.Sets/src/mage/cards/p/PowerArmor.java +++ b/Mage.Sets/src/mage/cards/p/PowerArmor.java @@ -36,6 +36,7 @@ import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; @@ -48,13 +49,14 @@ import mage.target.common.TargetCreaturePermanent; public class PowerArmor extends CardImpl { public PowerArmor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Domain - {3}, {tap}: Target creature gets +1/+1 until end of turn for each basic land type among lands you control. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect( new DomainValue(), new DomainValue(), Duration.EndOfTurn), new TapSourceCost()); ability.addCost(new ManaCostsImpl("{3}")); ability.addTarget(new TargetCreaturePermanent()); + ability.setAbilityWord(AbilityWord.DOMAIN); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PrisonBarricade.java b/Mage.Sets/src/mage/cards/p/PrisonBarricade.java index c5f63fd01a..1e9e12b7c3 100644 --- a/Mage.Sets/src/mage/cards/p/PrisonBarricade.java +++ b/Mage.Sets/src/mage/cards/p/PrisonBarricade.java @@ -46,26 +46,28 @@ import mage.counters.CounterType; /** * * @author LoneFox - + * */ public class PrisonBarricade extends CardImpl { public PrisonBarricade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.WALL); this.power = new MageInt(1); this.toughness = new MageInt(3); - // Defender - this.addAbility(DefenderAbility.getInstance()); // Kicker {1}{W} this.addAbility(new KickerAbility("{1}{W}")); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + // If Prison Barricade was kicked, it enters the battlefield with a +1/+1 counter on it and with "Prison Barricade can attack as though it didn't have defender." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.instance, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); + KickedCondition.instance, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield)); this.addAbility(ability); - } + } public PrisonBarricade(final PrisonBarricade card) { super(card); diff --git a/Mage.Sets/src/mage/cards/p/Probe.java b/Mage.Sets/src/mage/cards/p/Probe.java index 9430f0c0da..35f7b37351 100644 --- a/Mage.Sets/src/mage/cards/p/Probe.java +++ b/Mage.Sets/src/mage/cards/p/Probe.java @@ -48,17 +48,17 @@ import mage.target.TargetPlayer; public class Probe extends CardImpl { public Probe(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Kicker {1}{B} this.addAbility(new KickerAbility("{1}{B}")); // Draw three cards, then discard two cards. - this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(3,2)); + this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(3, 2)); // If Probe was kicked, target player discards two cards. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new DiscardTargetEffect(2), - KickedCondition.instance, - "If {this} was kicked, target player discards two cards")); + new DiscardTargetEffect(2), + KickedCondition.instance, + "

If {this} was kicked, target player discards two cards")); } @Override @@ -70,7 +70,7 @@ public class Probe extends CardImpl { } } } - + public Probe(final Probe card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/p/Prohibit.java b/Mage.Sets/src/mage/cards/p/Prohibit.java index f7d8641138..1fe9390078 100644 --- a/Mage.Sets/src/mage/cards/p/Prohibit.java +++ b/Mage.Sets/src/mage/cards/p/Prohibit.java @@ -29,17 +29,17 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.filter.FilterSpell; -import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.constants.Outcome; import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; import mage.target.TargetSpell; /** @@ -48,34 +48,15 @@ import mage.target.TargetSpell; */ public class Prohibit extends CardImpl { - private static final FilterSpell filter2 = new FilterSpell("spell if its converted mana cost is 2 or less"); - private static final FilterSpell filter4 = new FilterSpell("spell if its converted mana cost is 4 or less"); - - static { - filter2.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); - filter4.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 5)); - } - public Prohibit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Kicker {2} this.addAbility(new KickerAbility("{2}")); // Counter target spell if its converted mana cost is 2 or less. If Prohibit was kicked, counter that spell if its converted mana cost is 4 or less instead. this.getSpellAbility().addEffect(new CounterTargetEffect()); - this.getSpellAbility().addTarget(new TargetSpell(filter4)); - } - - @Override - public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility) { - if (!KickedCondition.instance.apply(game, ability)) { - ability.getTargets().clear(); - ability.getTargets().add(new TargetSpell(filter2)); - } - } + this.getSpellAbility().addTarget(new TargetSpell()); } public Prohibit(final Prohibit card) { @@ -87,3 +68,36 @@ public class Prohibit extends CardImpl { return new Prohibit(this); } } + +class OverloadEffect extends OneShotEffect { + + OverloadEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Counter target spell if its converted mana cost is 2 or less. If {this} was kicked, counter that spell if its converted mana cost is 4 or less instead."; + } + + OverloadEffect(final OverloadEffect effect) { + super(effect); + } + + @Override + public OverloadEffect copy() { + return new OverloadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Spell targetSpell = game.getSpell(this.getTargetPointer().getFirst(game, source)); + if (targetSpell != null) { + int cmc = targetSpell.getConvertedManaCost(); + if (cmc <= 2 || (KickedCondition.instance.apply(game, source) && cmc <= 4)) { + targetSpell.counter(source.getSourceId(), game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PyreZombie.java b/Mage.Sets/src/mage/cards/p/PyreZombie.java index 86200277be..7dc0441124 100644 --- a/Mage.Sets/src/mage/cards/p/PyreZombie.java +++ b/Mage.Sets/src/mage/cards/p/PyreZombie.java @@ -52,15 +52,15 @@ import mage.target.common.TargetCreatureOrPlayer; public class PyreZombie extends CardImpl { public PyreZombie(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); this.subtype.add(SubType.ZOMBIE); this.power = new MageInt(2); this.toughness = new MageInt(1); // At the beginning of your upkeep, if Pyre Zombie is in your graveyard, you may pay {1}{B}{B}. If you do, return Pyre Zombie to your hand. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, - new DoIfCostPaid(new ReturnToHandSourceEffect(), new ManaCostsImpl("{1}{B}{B}")), - TargetController.YOU, false)); + new DoIfCostPaid(new ReturnToHandSourceEffect().setText("return {this} to your hand"), new ManaCostsImpl("{1}{B}{B}")), + TargetController.YOU, false)); // {1}{R}{R}, Sacrifice Pyre Zombie: Pyre Zombie deals 2 damage to target creature or player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl("{1}{R}{R}")); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java b/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java index 7904d92d3a..9da954dd66 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverDagger.java @@ -41,6 +41,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; @@ -55,22 +56,24 @@ import mage.target.common.TargetCreaturePermanent; public class QuicksilverDagger extends CardImpl { public QuicksilverDagger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{R}"); 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 has "{tap}: This creature deals 1 damage to target player. You draw a card." Ability gainAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); gainAbility.addTarget(new TargetPlayer()); gainAbility.addEffect(new DrawCardSourceControllerEffect(1)); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainAbility, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityAttachedEffect(gainAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, + "Enchanted creature has \"{tap}: This creature deals 1 damage to target player. You draw a card.\"") + )); } public QuicksilverDagger(final QuicksilverDagger card) { diff --git a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java index 24d7e351d2..ee26c88734 100644 --- a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java +++ b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java @@ -36,7 +36,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterBasicLandCard; import mage.target.common.TargetCardInLibrary; /** @@ -46,14 +45,14 @@ import mage.target.common.TargetCardInLibrary; public class QuirionTrailblazer extends CardImpl { public QuirionTrailblazer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SCOUT); this.power = new MageInt(1); this.toughness = new MageInt(2); // When Quirion Trailblazer enters the battlefield, you may search your library for a basic land card and put that card onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); } public QuirionTrailblazer(final QuirionTrailblazer card) { diff --git a/Mage.Sets/src/mage/cards/r/RedManaBattery.java b/Mage.Sets/src/mage/cards/r/RedManaBattery.java index 2b6fbe11d0..224f287c21 100644 --- a/Mage.Sets/src/mage/cards/r/RedManaBattery.java +++ b/Mage.Sets/src/mage/cards/r/RedManaBattery.java @@ -67,7 +67,7 @@ public class RedManaBattery extends CardImpl { "Add {R} to your mana pool, then add {R} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java b/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java index bfda5d16f0..48c4854bb8 100644 --- a/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java +++ b/Mage.Sets/src/mage/cards/r/RewardsOfDiversity.java @@ -44,7 +44,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class RewardsOfDiversity extends CardImpl { - private static final FilterSpell filter = new FilterSpell("multicolored spell"); + private static final FilterSpell filter = new FilterSpell("a multicolored spell"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); @@ -52,7 +52,7 @@ public class RewardsOfDiversity extends CardImpl { } public RewardsOfDiversity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Whenever an opponent casts a multicolored spell, you gain 4 life. this.addAbility(new SpellCastOpponentTriggeredAbility(new GainLifeEffect(4), filter, false)); diff --git a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java index 75ab550c54..0b5dcc205c 100644 --- a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java +++ b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java @@ -53,15 +53,15 @@ import mage.util.CardUtil; * @author LevelX2 */ public class RisenExecutioner extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Zombie creatures"); - + static { filter.add(new SubtypePredicate(SubType.ZOMBIE)); } - + public RisenExecutioner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(4); @@ -69,16 +69,16 @@ public class RisenExecutioner extends CardImpl { // Risen Executioner can't block. this.addAbility(new CantBlockAbility()); - + // Other Zombie creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); - + // You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard. // TODO: cost increase does not happen if Risen Executioner is cast grom graveyard because of other effects Ability ability = new SimpleStaticAbility(Zone.ALL, new RisenExecutionerCastEffect()); ability.addEffect(new RisenExecutionerCostIncreasingEffect()); this.addAbility(ability); - + } public RisenExecutioner(final RisenExecutioner card) { @@ -92,10 +92,10 @@ public class RisenExecutioner extends CardImpl { } class RisenExecutionerCastEffect extends AsThoughEffectImpl { - + RisenExecutionerCastEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit); - staticText = "You may cast {this} from your graveyard"; + staticText = "You may cast {this} from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard"; } RisenExecutionerCastEffect(final RisenExecutionerCastEffect effect) { @@ -116,8 +116,8 @@ class RisenExecutionerCastEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); - if (card != null - && card.getOwnerId().equals(affectedControllerId) + if (card != null + && card.getOwnerId().equals(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { return true; } @@ -129,14 +129,14 @@ class RisenExecutionerCastEffect extends AsThoughEffectImpl { class RisenExecutionerCostIncreasingEffect extends CostModificationEffectImpl { protected static final FilterCreatureCard filter = new FilterCreatureCard(); - + static { filter.add(new AnotherCardPredicate()); } - - RisenExecutionerCostIncreasingEffect () { + + RisenExecutionerCostIncreasingEffect() { super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.INCREASE_COST); - staticText = "if you pay {1} more to cast it for each other creature card in your graveyard"; + staticText = ""; } RisenExecutionerCostIncreasingEffect(final RisenExecutionerCostIncreasingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/r/RoilingHorror.java b/Mage.Sets/src/mage/cards/r/RoilingHorror.java index fe6d3c8f91..dcb8b43196 100644 --- a/Mage.Sets/src/mage/cards/r/RoilingHorror.java +++ b/Mage.Sets/src/mage/cards/r/RoilingHorror.java @@ -59,18 +59,20 @@ import mage.target.TargetPlayer; public class RoilingHorror extends CardImpl { public RoilingHorror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.HORROR); this.power = new MageInt(0); this.toughness = new MageInt(0); // Roiling Horror's power and toughness are each equal to your life total minus the life total of an opponent with the most life. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new RoilingHorrorDynamicValue(), Duration.EndOfGame))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new RoilingHorrorDynamicValue(), Duration.EndOfGame) + .setText("{this}'s power and toughness are each equal to your life total minus the life total of an opponent with the most life.") + )); // Suspend X-{X}{B}{B}{B}. X can't be 0. this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl("{B}{B}{B}"), this, true)); - + // Whenever a time counter is removed from Roiling Horror while it's exiled, target player loses 1 life and you gain 1 life. this.addAbility(new RoilingHorrorTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java b/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java index 77c70ea0e2..e15ba49ae2 100644 --- a/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java +++ b/Mage.Sets/src/mage/cards/s/SaprolingSymbiosis.java @@ -43,17 +43,18 @@ import mage.game.permanent.token.SaprolingToken; /** * * @author LoneFox - + * */ public class SaprolingSymbiosis extends CardImpl { public SaprolingSymbiosis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); Effect effect = new CreateTokenEffect(new SaprolingToken(), new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent())); // You may cast Saproling Symbiosis as though it had flash if you pay {2} more to cast it. Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl("{2}")); ability.addEffect(effect); + ability.setRuleAtTheTop(true); this.addAbility(ability); // Create a 1/1 green Saproling creature token for each creature you control. this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java index be4e25985e..48a642f9b1 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCardInLibrary; */ public class SarkhanUnbroken extends CardImpl { - private static final FilterCard dragonFilter = new FilterCard("Dragon creature card"); + private static final FilterCard dragonFilter = new FilterCard("Dragon creature cards"); static { dragonFilter.add(new SubtypePredicate(SubType.DRAGON)); diff --git a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java index ba3e595729..27ab1c640a 100644 --- a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java +++ b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java @@ -65,7 +65,7 @@ public class SawtoothLoon extends CardImpl { } public SawtoothLoon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -94,7 +94,7 @@ class SawtoothLoonEffect extends OneShotEffect { public SawtoothLoonEffect() { super(Outcome.DrawCard); - this.staticText = "Draw two cards, then put two cards from your hand on the bottom of your library"; + this.staticText = "draw two cards, then put two cards from your hand on the bottom of your library"; } public SawtoothLoonEffect(final SawtoothLoonEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java index e354df9011..c1d7edba64 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java +++ b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java @@ -81,7 +81,7 @@ class ScaleBlessingEffect extends OneShotEffect { public ScaleBlessingEffect() { super(Outcome.Benefit); - this.staticText = ", then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. "; + this.staticText = ", then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. (To bolster 1, choose a creature with the least toughness among creatures you control and put +1/+1 counter on it.)"; } public ScaleBlessingEffect(final ScaleBlessingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java index 03828716ff..c0a19bac1d 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java +++ b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java @@ -62,7 +62,7 @@ public class ScaleguardSentinels extends CardImpl { } public ScaleguardSentinels(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); @@ -74,7 +74,7 @@ public class ScaleguardSentinels extends CardImpl { // Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), ScaleguardSentinelsCondition.instance, - "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}", ""), + "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}.", ""), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/ScorchingLava.java b/Mage.Sets/src/mage/cards/s/ScorchingLava.java index 51bb207a58..3ce722d731 100644 --- a/Mage.Sets/src/mage/cards/s/ScorchingLava.java +++ b/Mage.Sets/src/mage/cards/s/ScorchingLava.java @@ -65,8 +65,9 @@ public class ScorchingLava extends CardImpl { this.getSpellAbility().addEffect(new ConditionalContinuousRuleModifyingEffect( new CantRegenerateTargetEffect(Duration.EndOfTurn, "that creature"), new LockedInCondition(KickedCondition.instance))); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - (OneShotEffect) new ExileTargetIfDiesEffect().setText("and if it would die this turn, exile it instead"), - new LockedInCondition(KickedCondition.instance))); + new ExileTargetIfDiesEffect(), + new LockedInCondition(KickedCondition.instance) + ).setText("and if it would die this turn, exile it instead")); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/cards/s/SeersVision.java b/Mage.Sets/src/mage/cards/s/SeersVision.java index 389d362363..c4f694f0f7 100644 --- a/Mage.Sets/src/mage/cards/s/SeersVision.java +++ b/Mage.Sets/src/mage/cards/s/SeersVision.java @@ -48,12 +48,12 @@ import mage.target.TargetPlayer; public class SeersVision extends CardImpl { public SeersVision(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}"); // Your opponents play with their hands revealed. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithHandRevealedEffect(TargetController.OPPONENT))); // Sacrifice Seer's Vision: Look at target player's hand and choose a card from it. That player discards that card. Activate this ability only any time you could cast a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardCardYouChooseTargetEffect(), new SacrificeSourceCost()); + Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardCardYouChooseTargetEffect(TargetController.ANY), new SacrificeSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java b/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java index b4c2ffd74b..f8e235f3db 100644 --- a/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java +++ b/Mage.Sets/src/mage/cards/s/ServantOfTheScale.java @@ -55,7 +55,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class ServantOfTheScale extends CardImpl { public ServantOfTheScale(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(0); @@ -63,7 +63,7 @@ public class ServantOfTheScale extends CardImpl { // Servant of the Scale enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - "with a +1/+1 counters on it")); + "with a +1/+1 counter on it")); // When Servant of the Scale dies, put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counter on Servant of the Scale. Ability ability = new DiesTriggeredAbility(new ServantOfTheScaleEffect(), false); @@ -85,7 +85,7 @@ class ServantOfTheScaleEffect extends OneShotEffect { public ServantOfTheScaleEffect() { super(Outcome.BoostCreature); - this.staticText = "put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counter on {this}"; + this.staticText = "put X +1/+1 counters on target creature you control, where X is the number of +1/+1 counters on {this}"; } public ServantOfTheScaleEffect(final ServantOfTheScaleEffect effect) { @@ -101,8 +101,8 @@ class ServantOfTheScaleEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (sourcePermanent != null && controller != null && - (sourcePermanent.getZoneChangeCounter(game) == source.getSourceObjectZoneChangeCounter() // Token + if (sourcePermanent != null && controller != null + && (sourcePermanent.getZoneChangeCounter(game) == source.getSourceObjectZoneChangeCounter() // Token || sourcePermanent.getZoneChangeCounter(game) + 1 == source.getSourceObjectZoneChangeCounter())) { // PermanentCard int amount = sourcePermanent.getCounters(game).getCount(CounterType.P1P1); if (amount > 0) { diff --git a/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java b/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java index 4a855a92b6..329a6620be 100644 --- a/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java +++ b/Mage.Sets/src/mage/cards/s/ShieldhideDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class ShieldhideDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class ShieldhideDragon extends CardImpl { } public ShieldhideDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // Lifelink this.addAbility(LifelinkAbility.getInstance()); - + // Megamorph {5}{W}{W} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{W}{W}"), true)); - + // When Shieldhide Dragon is turned face up, put a +1/+1 counter on each other Dragon you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java b/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java index 1ddb95a8b7..77fbf8d6b7 100644 --- a/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java +++ b/Mage.Sets/src/mage/cards/s/SightOfTheScalelords.java @@ -59,11 +59,11 @@ public class SightOfTheScalelords extends CardImpl { } public SightOfTheScalelords(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); // At the beginning of combat on your turn, creature you control with toughness 4 or greater get +2/+2 and gain vigilance until end of turn. - Effect effect = new BoostControlledEffect(2,2,Duration.EndOfTurn, filter, false); - effect.setText("creature you control with toughness 4 or greater get +2/+2"); + Effect effect = new BoostControlledEffect(2, 2, Duration.EndOfTurn, filter, false); + effect.setText("creatures you control with toughness 4 or greater get +2/+2"); Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, false, false); effect = new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, filter); effect.setText("and gain vigilance until end of turn"); diff --git a/Mage.Sets/src/mage/cards/s/StormriderRig.java b/Mage.Sets/src/mage/cards/s/StormriderRig.java index 1257360455..740d3e3025 100644 --- a/Mage.Sets/src/mage/cards/s/StormriderRig.java +++ b/Mage.Sets/src/mage/cards/s/StormriderRig.java @@ -50,20 +50,20 @@ import mage.filter.common.FilterControlledCreaturePermanent; public class StormriderRig extends CardImpl { public StormriderRig(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); + // Whenever a creature enters the battlefield under your control, you may attach Stormrider Rig to it. this.addAbility(new EntersBattlefieldAllTriggeredAbility( Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), - new FilterControlledCreaturePermanent(), true, SetTargetPointer.PERMANENT, null, true)); - + new FilterControlledCreaturePermanent("a creature"), true, SetTargetPointer.PERMANENT, null, true)); + // Equip {2} - this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); - + this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); + } public StormriderRig(final StormriderRig card) { diff --git a/Mage.Sets/src/mage/cards/s/StormscapeMaster.java b/Mage.Sets/src/mage/cards/s/StormscapeMaster.java index fa30ec1d16..2fc0a0097e 100644 --- a/Mage.Sets/src/mage/cards/s/StormscapeMaster.java +++ b/Mage.Sets/src/mage/cards/s/StormscapeMaster.java @@ -49,12 +49,12 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class StormscapeMaster extends CardImpl { public StormscapeMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(2); @@ -70,7 +70,7 @@ public class StormscapeMaster extends CardImpl { // {B}{B}, {T}: Target player loses 2 life and you gain 2 life. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2), new ManaCostsImpl("{B}{B}")); - ability.addEffect(new GainLifeEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/StormwingDragon.java b/Mage.Sets/src/mage/cards/s/StormwingDragon.java index e16ba6e75f..daae80e3be 100644 --- a/Mage.Sets/src/mage/cards/s/StormwingDragon.java +++ b/Mage.Sets/src/mage/cards/s/StormwingDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class StormwingDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,20 +58,20 @@ public class StormwingDragon extends CardImpl { } public StormwingDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); // Flying this.addAbility(FlyingAbility.getInstance()); - + // First strike this.addAbility(FirstStrikeAbility.getInstance()); - + // Megamorph {5}{R}{R} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{R}{R}"), true)); - + // When Stormwing Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SulfurElemental.java b/Mage.Sets/src/mage/cards/s/SulfurElemental.java index a43214d4a4..741e04f513 100644 --- a/Mage.Sets/src/mage/cards/s/SulfurElemental.java +++ b/Mage.Sets/src/mage/cards/s/SulfurElemental.java @@ -48,25 +48,28 @@ import mage.filter.predicate.mageobject.ColorPredicate; * @author LevelX2 */ public class SulfurElemental extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creatures"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); } public SulfurElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(3); this.toughness = new MageInt(2); - // Flash - this.addAbility(FlashAbility.getInstance()); // Split second this.addAbility(new SplitSecondAbility()); + + // Flash + this.addAbility(FlashAbility.getInstance()); + // White creatures get +1/-1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,-1, Duration.WhileOnBattlefield, filter, false))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, -1, Duration.WhileOnBattlefield, filter, false))); } public SulfurElemental(final SulfurElemental card) { diff --git a/Mage.Sets/src/mage/cards/t/TemporalDistortion.java b/Mage.Sets/src/mage/cards/t/TemporalDistortion.java index 1a18ec7e82..302059905e 100644 --- a/Mage.Sets/src/mage/cards/t/TemporalDistortion.java +++ b/Mage.Sets/src/mage/cards/t/TemporalDistortion.java @@ -57,7 +57,7 @@ import mage.game.permanent.Permanent; */ public class TemporalDistortion extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("creature or land"); + private static final FilterPermanent filter = new FilterPermanent("a creature or land"); private static final FilterPermanent filter2 = new FilterPermanent("permanents with hourglass counters on them"); static { diff --git a/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java b/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java index b6f623d1f2..f7e84c7e1a 100644 --- a/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java +++ b/Mage.Sets/src/mage/cards/t/ThunderscapeMaster.java @@ -51,7 +51,7 @@ import mage.target.TargetPlayer; public class ThunderscapeMaster extends CardImpl { public ThunderscapeMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -60,7 +60,7 @@ public class ThunderscapeMaster extends CardImpl { // {B}{B}, {tap}: Target player loses 2 life and you gain 2 life. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2), new ManaCostsImpl("{B}{B}")); - ability.addEffect(new GainLifeEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java b/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java index 8a00564be4..2ce0b055bd 100644 --- a/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java +++ b/Mage.Sets/src/mage/cards/u/UrborgSkeleton.java @@ -24,7 +24,7 @@ * 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.u; import java.util.UUID; @@ -45,15 +45,15 @@ import mage.constants.Zone; import mage.counters.CounterType; /** -* -* @author LevelX2 -*/ + * + * @author LevelX2 + */ public class UrborgSkeleton extends CardImpl { - private static final String staticText = "If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it"; + private static final String staticText = "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it."; public UrborgSkeleton(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.SKELETON); this.power = new MageInt(0); @@ -68,7 +68,7 @@ public class UrborgSkeleton extends CardImpl { // If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it. Ability ability = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.instance, staticText,""); + KickedCondition.instance, staticText, ""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VodalianMerchant.java b/Mage.Sets/src/mage/cards/v/VodalianMerchant.java index 448e135a9d..c63300fd07 100644 --- a/Mage.Sets/src/mage/cards/v/VodalianMerchant.java +++ b/Mage.Sets/src/mage/cards/v/VodalianMerchant.java @@ -29,7 +29,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -43,13 +43,13 @@ import mage.constants.SubType; public class VodalianMerchant extends CardImpl { public VodalianMerchant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.MERFOLK); this.power = new MageInt(1); this.toughness = new MageInt(2); // When Vodalian Merchant enters the battlefield, draw a card, then discard a card. - this.addAbility(new EntersBattlefieldAbility(new DrawDiscardControllerEffect(1, 1, false))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1, false))); } public VodalianMerchant(final VodalianMerchant card) { diff --git a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java index fada4c7f92..9e78d925f2 100644 --- a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java +++ b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java @@ -67,7 +67,7 @@ public class WhiteManaBattery extends CardImpl { "Add {W} to your mana pool, then add {W} to your mana pool for each storage counter removed this way", true, new CountersSourceCount(CounterType.STORAGE)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove X storage counters from {this}")); + "Remove any number of storage counters from {this}")); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index 9c8e54dd50..5e4ea50e9a 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -480,21 +480,21 @@ public class Mana implements Comparable, Serializable, Copyable { for (int i = 0; i < colorless; i++) { sbMana.append("{C}"); } + for (int i = 0; i < white; i++) { + sbMana.append("{W}"); + } + for (int i = 0; i < blue; i++) { + sbMana.append("{U}"); + } + for (int i = 0; i < black; i++) { + sbMana.append("{B}"); + } for (int i = 0; i < red; i++) { sbMana.append("{R}"); } for (int i = 0; i < green; i++) { sbMana.append("{G}"); } - for (int i = 0; i < blue; i++) { - sbMana.append("{U}"); - } - for (int i = 0; i < white; i++) { - sbMana.append("{W}"); - } - for (int i = 0; i < black; i++) { - sbMana.append("{B}"); - } for (int i = 0; i < any; i++) { sbMana.append("{Any}"); } diff --git a/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java b/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java index 599b1a2d81..3faa62f5c4 100644 --- a/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PayMoreToCastAsThoughtItHadFlashAbility.java @@ -26,7 +26,7 @@ public class PayMoreToCastAsThoughtItHadFlashAbility extends SpellAbility { super(card.getSpellAbility().getManaCosts().copy(), card.getName() + " as though it had flash", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); this.costsToAdd = costsToAdd; this.timing = TimingRule.INSTANT; - + this.ruleAtTheTop = true; CardUtil.increaseCost(this, costsToAdd); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java b/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java index 9025cf0af4..e434c86002 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/CardsInHandCondition.java @@ -45,7 +45,6 @@ import mage.util.CardUtil; */ public class CardsInHandCondition implements Condition { - private Condition condition; private ComparisonType type; private int count; @@ -114,7 +113,7 @@ public class CardsInHandCondition implements Condition { @Override public String toString() { int workCount = count; - StringBuilder sb = new StringBuilder("if "); + StringBuilder sb = new StringBuilder("if"); switch (targetController) { case YOU: sb.append(" you have"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java index 2da6d5747f..14803dfc47 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java @@ -35,6 +35,7 @@ import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.choices.ChoiceColor; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; /** * @author noxx @@ -59,8 +60,10 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { this.manaBuilder = manaBuilder; this.oneChoice = oneChoice; // - staticText = "Add " + amount + " mana of " - + (oneChoice ? "any one color" : "in any combination of colors") + staticText = "Add " + + (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "") + + " mana " + + (oneChoice ? "of any one color" : "in any combination of colors") + " to your mana pool. " + manaBuilder.getRule(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java b/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java index f1c4c1d3a5..97a11cd3e7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CastSourceTriggeredAbility.java @@ -46,11 +46,12 @@ public class CastSourceTriggeredAbility extends TriggeredAbilityImpl { public CastSourceTriggeredAbility(Effect effect) { this(effect, false); } - + public CastSourceTriggeredAbility(Effect effect, boolean optional) { super(Zone.STACK, effect, optional); + this.ruleAtTheTop = true; } - + public CastSourceTriggeredAbility(final CastSourceTriggeredAbility ability) { super(ability); } @@ -70,7 +71,7 @@ public class CastSourceTriggeredAbility extends TriggeredAbilityImpl { if (event.getSourceId().equals(this.getSourceId())) { MageObject spellObject = game.getObject(sourceId); if (spellObject != null && (spellObject instanceof Spell)) { - Spell spell = (Spell)spellObject; + Spell spell = (Spell) spellObject; if (spell.getSpellAbility() != null) { for (Effect effect : getEffects()) { effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java index a409e5b1fd..d0cdc8fdf2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CounterUnlessPaysEffect.java @@ -113,7 +113,7 @@ public class CounterUnlessPaysEffect extends OneShotEffect { if (mode.getTargets().isEmpty()) { sb.append("counter it"); } else { - sb.append("Counter target ").append(mode.getTargets().get(0).getTargetName()); + sb.append("counter target ").append(mode.getTargets().get(0).getTargetName()); } sb.append(" unless its controller pays "); if (cost != null) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java index 796fb67700..79bd6484f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common; +import java.util.List; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -45,7 +46,7 @@ public class GetEmblemEffect extends OneShotEffect { public GetEmblemEffect(Emblem emblem) { super(Outcome.Benefit); this.emblem = emblem; - this.staticText = "You get an emblem with \"" + emblem.getAbilities().getRules(null) + '"'; + this.staticText = "You get an emblem with \"" + +'"'; } public GetEmblemEffect(final GetEmblemEffect effect) { @@ -68,4 +69,21 @@ public class GetEmblemEffect extends OneShotEffect { return true; } + public String getText() { + StringBuilder sb = new StringBuilder(); + sb.append("You get an emblem with \""); + List rules = emblem.getAbilities().getRules(null); + if (rules.size() == 1) { + sb.append(rules.get(0)); + sb.append('"'); + } else if (rules.size() == 2) { + for (String s : rules) { + sb.append(s); + sb.append("\" and \""); + } + sb.append('"'); + } + sb.append('.'); + return sb.toString(); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java index 63effc4e1c..8c0d69c78c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/NameACardEffect.java @@ -82,27 +82,27 @@ public class NameACardEffect extends OneShotEffect { switch (typeOfName) { case ALL: cardChoice.setChoices(CardRepository.instance.getNames()); - cardChoice.setMessage("Name a card"); + cardChoice.setMessage("Choose a card name"); break; case NON_ARTIFACT_AND_NON_LAND_NAME: cardChoice.setChoices(CardRepository.instance.getNonArtifactAndNonLandNames()); - cardChoice.setMessage("Name a non artifact and non land card"); + cardChoice.setMessage("Choose a nonartifact, nonland card name"); break; case NON_LAND_AND_NON_CREATURE_NAME: cardChoice.setChoices(CardRepository.instance.getNonLandAndNonCreatureNames()); - cardChoice.setMessage("Name a non land and non creature card"); + cardChoice.setMessage("Choose a nonland and non creature card"); break; case NON_LAND_NAME: cardChoice.setChoices(CardRepository.instance.getNonLandNames()); - cardChoice.setMessage("Name a non land card"); + cardChoice.setMessage("Choose a nonland card name"); break; case CREATURE_NAME: cardChoice.setChoices(CardRepository.instance.getCreatureNames()); - cardChoice.setMessage("Name a creature card"); + cardChoice.setMessage("Choose a creature card name"); break; case ARTIFACT_NAME: cardChoice.setChoices(CardRepository.instance.getArtifactNames()); - cardChoice.setMessage("Name an artifact card"); + cardChoice.setMessage("Choose an artifact card name"); break; } cardChoice.clearChoice(); @@ -130,7 +130,7 @@ public class NameACardEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("name a "); + StringBuilder sb = new StringBuilder("choose a "); switch (typeOfName) { case ALL: sb.append("card"); @@ -139,7 +139,7 @@ public class NameACardEffect extends OneShotEffect { sb.append("nonartifact, nonland card"); break; case NON_LAND_AND_NON_CREATURE_NAME: - sb.append("card other than a creature or a land card"); + sb.append("noncreature, nonland card"); break; case NON_LAND_NAME: sb.append("nonland card"); @@ -151,6 +151,7 @@ public class NameACardEffect extends OneShotEffect { sb.append("artifact card"); break; } + sb.append(" name"); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java index f5a366b6c1..7cf8dbfd71 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/UntapAllThatAttackedEffect.java @@ -48,7 +48,7 @@ public class UntapAllThatAttackedEffect extends OneShotEffect { public UntapAllThatAttackedEffect() { super(Outcome.Benefit); - staticText = " Untap all creatures that attacked this turn"; + staticText = "Untap all creatures that attacked this turn"; } public UntapAllThatAttackedEffect(final UntapAllThatAttackedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java index fdd2aefac5..fae351becc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByAllTargetEffect.java @@ -30,6 +30,7 @@ package mage.abilities.effects.common.combat; import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; import mage.constants.Duration; +import static mage.constants.Duration.EndOfTurn; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -45,8 +46,9 @@ public class CantBeBlockedByAllTargetEffect extends RestrictionEffect { public CantBeBlockedByAllTargetEffect(FilterCreaturePermanent filterBlockedBy, Duration duration) { super(duration); this.filterBlockedBy = filterBlockedBy; - staticText = "Target creature" + staticText = "target creature" + " can't be blocked " + + (duration == EndOfTurn ? "this turn " : "") + (filterBlockedBy.getMessage().startsWith("except by") ? "" : "by ") + filterBlockedBy.getMessage(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java index 884cc61e3a..4b9eedc8f6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEnchantedEffect.java @@ -125,7 +125,7 @@ public class BoostEnchantedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Enchanted creature gets "); + sb.append("enchanted creature gets "); String p = power.toString(); if (!p.startsWith("-")) { sb.append('+'); diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java index 52f45373b0..75ba52ece3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java @@ -37,6 +37,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; /** * @@ -106,9 +107,9 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { sb.append("search your library for "); if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) { if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) { - sb.append("any number of ").append(' '); + sb.append("any number of "); } else { - sb.append("up to ").append(target.getMaxNumberOfTargets()).append(' '); + sb.append("up to ").append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(' '); } sb.append(target.getTargetName()).append(" and put them onto the battlefield"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java index c29a2ef4cf..c090088572 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/BolsterEffect.java @@ -122,7 +122,7 @@ public class BolsterEffect extends OneShotEffect { } else { sb.append("X, where X is the number of "); sb.append(amount.getMessage()); - sb.append(". (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)"); + sb.append(" (Choose a creature with the least toughness among creatures you control and put X +1/+1 counters on it.)"); } return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/keyword/DashAbility.java b/Mage/src/main/java/mage/abilities/keyword/DashAbility.java index 93a7f9fe42..96d2e45a43 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DashAbility.java @@ -78,6 +78,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), DashedCondition.instance, "", ""); ability.addEffect(new DashAddDelayedTriggeredAbilityEffect()); + ability.setRuleVisible(false); addSubAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java index 88e97204f6..b871cf0b81 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ReachAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.constants.Zone; @@ -40,7 +39,7 @@ import java.io.ObjectStreamException; */ public class ReachAbility extends StaticAbility implements MageSingleton { - private static final ReachAbility instance = new ReachAbility(); + private static final ReachAbility instance = new ReachAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -56,7 +55,7 @@ public class ReachAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Reach"; + return "reach"; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java index 3382b061db..0921b18e12 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java @@ -166,7 +166,7 @@ public class SuspendAbility extends SpecialAction { } StringBuilder sb = new StringBuilder("Suspend "); if (cost != null) { - sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append(" - ").append(cost.getText()); + sb.append(suspend == Integer.MAX_VALUE ? "X" : suspend).append(" - ").append(cost.getText()).append(suspend == Integer.MAX_VALUE ? ". X can't be 0" : ""); if (!shortRule) { sb.append(" (Rather than cast this card from your hand, pay ") .append(cost.getText()) From 54b8f10c3cdd01da8c3717950f1a5231cef7e3b6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 7 Oct 2017 16:08:06 -0400 Subject: [PATCH 68/68] text fixes and test fixes to fix how tests test text, then more text next --- .../src/mage/cards/b/BanishingKnack.java | 8 ++-- .../src/mage/cards/b/BelltollDragon.java | 8 ++-- .../src/mage/cards/b/BlackManaBattery.java | 8 ++-- .../src/mage/cards/b/BlueManaBattery.java | 8 ++-- Mage.Sets/src/mage/cards/d/DeityOfScars.java | 5 +-- .../src/mage/cards/d/DescentOfTheDragons.java | 2 +- .../src/mage/cards/d/DuergarMineCaptain.java | 11 ++++-- .../src/mage/cards/d/DutifulAttendant.java | 4 +- .../src/mage/cards/f/FieryBombardment.java | 9 +++-- Mage.Sets/src/mage/cards/f/FireAtWill.java | 5 +-- Mage.Sets/src/mage/cards/g/GilderBairn.java | 4 +- .../src/mage/cards/g/GleamOfAuthority.java | 4 +- .../src/mage/cards/g/GreenManaBattery.java | 8 ++-- Mage.Sets/src/mage/cards/h/HelixPinnacle.java | 2 +- .../src/mage/cards/m/MerrowBonegnawer.java | 4 +- Mage.Sets/src/mage/cards/m/Moonhold.java | 8 ++-- Mage.Sets/src/mage/cards/n/NightskyMimic.java | 4 +- Mage.Sets/src/mage/cards/p/PunctureBlast.java | 3 +- .../src/mage/cards/r/RedManaBattery.java | 8 ++-- .../src/mage/cards/r/RekindledFlame.java | 19 ++++++---- Mage.Sets/src/mage/cards/s/ScaleBlessing.java | 6 +-- .../src/mage/cards/s/ShorecrasherMimic.java | 4 +- Mage.Sets/src/mage/cards/t/TalarasBane.java | 15 ++++---- .../src/mage/cards/u/UnnervingAssault.java | 16 ++++---- Mage.Sets/src/mage/cards/w/WakeThrasher.java | 10 ++--- Mage.Sets/src/mage/cards/w/WardOfBones.java | 4 +- .../src/mage/cards/w/WhiteManaBattery.java | 8 ++-- .../abilities/keywords/DeathtouchTest.java | 4 +- .../abilities/keywords/ManifestTest.java | 8 ++-- .../cards/abilities/keywords/SuspendTest.java | 2 +- .../oneshot/exile/ExileAndReturnTest.java | 6 +-- .../oneshot/sacrifice/TradingPostTest.java | 2 +- .../other/SoulfireGrandMasterTest.java | 2 +- .../continuous/AngelOfJubilationTest.java | 6 +-- .../cards/continuous/SerraAscendantTest.java | 2 +- .../cards/control/ExchangeControlTest.java | 2 +- .../control/GainControlDiedCastAgainTest.java | 2 +- .../control/GainControlTargetEffectTest.java | 6 +-- .../test/cards/control/WillbreakerTest.java | 2 +- .../cards/copy/FeldonOfTheThirdPathTest.java | 4 +- .../test/cards/copy/IsochronScepterTest.java | 8 ++-- .../mage/test/cards/copy/MimicVatTest.java | 8 ++-- .../additional/RemoveCounterCostTest.java | 2 +- .../cost/modification/HeartstoneTest.java | 2 +- .../cards/enchantments/SkullclampTest.java | 2 +- .../test/cards/mana/ConditionalManaTest.java | 2 +- .../mage/test/cards/mana/CryptGhastTest.java | 2 +- .../test/cards/mana/DoublingCubeTest.java | 6 +-- .../test/cards/mana/HarvesterDruidTest.java | 12 +++--- .../cards/mana/NykthosShrineToNyxTest.java | 14 +++---- .../test/cards/mana/ReflectingPoolTest.java | 8 ++-- .../test/cards/mana/SylvokExplorerTest.java | 4 +- .../cards/replacement/GrindstoneTest.java | 37 +++++++++---------- .../replacement/LeylineOfTheVoidTest.java | 2 +- .../ZoneChangeReplacementTest.java | 4 +- .../cards/single/ContagionEngineTest.java | 2 +- .../cards/single/MagewrightStoneTest.java | 2 +- .../test/cards/single/SoulFoundryTest.java | 2 +- .../cards/single/mir/GrinningTotemTest.java | 4 +- .../cards/triggers/BecomesTheTargetTest.java | 2 +- .../test/cards/triggers/SpellskiteTest.java | 2 +- .../test/cards/watchers/FellShepherdTest.java | 2 +- .../multiplayer/BloodchiefAscensionTest.java | 2 +- .../abilities/ProtectionFromTypeTest.java | 4 +- .../org/mage/test/utils/ManaOptionsTest.java | 18 ++++----- .../main/java/mage/abilities/Abilities.java | 2 + .../java/mage/abilities/AbilitiesImpl.java | 9 ++++- .../java/mage/abilities/CompoundAbility.java | 2 +- .../costs/common/UntapTargetCost.java | 10 ++--- .../effects/common/GetEmblemEffect.java | 7 ++-- .../LookLibraryAndPickControllerEffect.java | 6 ++- .../combat/CantBlockAttachedEffect.java | 2 +- .../continuous/BoostEquippedEffect.java | 14 ++++--- .../abilities/keyword/ProtectionAbility.java | 2 +- .../mage/abilities/keyword/WitherAbility.java | 22 ++++++----- Mage/src/test/java/mage/ManaTest.java | 2 +- 76 files changed, 247 insertions(+), 227 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BanishingKnack.java b/Mage.Sets/src/mage/cards/b/BanishingKnack.java index 63501ca598..e583d54741 100644 --- a/Mage.Sets/src/mage/cards/b/BanishingKnack.java +++ b/Mage.Sets/src/mage/cards/b/BanishingKnack.java @@ -51,12 +51,14 @@ public class BanishingKnack extends CardImpl { private static final FilterPermanent filter = new FilterNonlandPermanent(); - public BanishingKnack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); + public BanishingKnack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new TapSourceCost()); gainedAbility.addTarget(new TargetPermanent(filter)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn) + .setText("Until end of turn, target creature gains \"{T}: Return target nonland permanent to its owner's hand.\"") + ); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/b/BelltollDragon.java b/Mage.Sets/src/mage/cards/b/BelltollDragon.java index a2eb839f71..8f62f096ab 100644 --- a/Mage.Sets/src/mage/cards/b/BelltollDragon.java +++ b/Mage.Sets/src/mage/cards/b/BelltollDragon.java @@ -49,8 +49,8 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author fireshoes */ public class BelltollDragon extends CardImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other Dragon creature you control"); static { filter.add(new AnotherPredicate()); @@ -58,7 +58,7 @@ public class BelltollDragon extends CardImpl { } public BelltollDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -69,7 +69,7 @@ public class BelltollDragon extends CardImpl { this.addAbility(HexproofAbility.getInstance()); // Megamorph {5}{U}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}{U}"), true)); - + // When Belltoll Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); } diff --git a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java index 412775a234..4b831bee4f 100644 --- a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java @@ -64,10 +64,10 @@ public class BlackManaBattery extends CardImpl { Mana.BlackMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {B} to your mana pool, then add {B} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {B} to your mana pool, then add {B} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java index 6883996517..4a16c87b1d 100644 --- a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java +++ b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java @@ -64,10 +64,10 @@ public class BlueManaBattery extends CardImpl { Mana.BlueMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {U} to your mana pool, then add {U} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {U} to your mana pool, then add {U} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DeityOfScars.java b/Mage.Sets/src/mage/cards/d/DeityOfScars.java index b996d9bc06..6d979524ba 100644 --- a/Mage.Sets/src/mage/cards/d/DeityOfScars.java +++ b/Mage.Sets/src/mage/cards/d/DeityOfScars.java @@ -50,11 +50,10 @@ import mage.counters.CounterType; public class DeityOfScars extends CardImpl { public DeityOfScars(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B/G}{B/G}{B/G}{B/G}{B/G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B/G}{B/G}{B/G}{B/G}{B/G}"); this.subtype.add(SubType.SPIRIT); this.subtype.add(SubType.AVATAR); - this.power = new MageInt(7); this.toughness = new MageInt(7); @@ -62,7 +61,7 @@ public class DeityOfScars extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Deity of Scars enters the battlefield with two -1/-1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)))); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), "with two -1/-1 counters on it")); // {B/G}, Remove a -1/-1 counter from Deity of Scars: Regenerate Deity of Scars. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B/G}")); diff --git a/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java b/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java index da4c02d0cd..a8ec7660aa 100644 --- a/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java +++ b/Mage.Sets/src/mage/cards/d/DescentOfTheDragons.java @@ -72,7 +72,7 @@ class DescentOfTheDragonsEffect extends OneShotEffect { public DescentOfTheDragonsEffect() { super(Outcome.Benefit); - staticText = "Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying"; + staticText = "Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying"; } public DescentOfTheDragonsEffect(final DescentOfTheDragonsEffect effect) { diff --git a/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java b/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java index 09b46d0ffd..aeb1283878 100644 --- a/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java +++ b/Mage.Sets/src/mage/cards/d/DuergarMineCaptain.java @@ -45,12 +45,12 @@ import mage.filter.common.FilterAttackingCreature; /** * * @author jeffwadsworth - + * */ public class DuergarMineCaptain extends CardImpl { public DuergarMineCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R/W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R/W}"); this.subtype.add(SubType.DWARF); this.subtype.add(SubType.SOLDIER); @@ -58,10 +58,13 @@ public class DuergarMineCaptain extends CardImpl { this.toughness = new MageInt(1); // {1}{RW}, {untap}: Attacking creatures get +1/+0 until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 0, Duration.EndOfTurn, new FilterAttackingCreature(), false), new ManaCostsImpl("{1}{R/W}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostAllEffect(1, 0, Duration.EndOfTurn, new FilterAttackingCreature("attacking creatures"), false), + new ManaCostsImpl("{1}{R/W}") + ); ability.addCost(new UntapSourceCost()); this.addAbility(ability); - + } public DuergarMineCaptain(final DuergarMineCaptain card) { diff --git a/Mage.Sets/src/mage/cards/d/DutifulAttendant.java b/Mage.Sets/src/mage/cards/d/DutifulAttendant.java index 98407cddd0..a3d5a5e2a8 100644 --- a/Mage.Sets/src/mage/cards/d/DutifulAttendant.java +++ b/Mage.Sets/src/mage/cards/d/DutifulAttendant.java @@ -46,14 +46,14 @@ import mage.target.common.TargetCardInYourGraveyard; */ public class DutifulAttendant extends CardImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard("another creature card from your graveyard"); + private static final FilterCreatureCard filter = new FilterCreatureCard("another target creature card from your graveyard"); static { filter.add(new AnotherCardPredicate()); } public DutifulAttendant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/f/FieryBombardment.java b/Mage.Sets/src/mage/cards/f/FieryBombardment.java index a7c51fa2b1..63d29ac716 100644 --- a/Mage.Sets/src/mage/cards/f/FieryBombardment.java +++ b/Mage.Sets/src/mage/cards/f/FieryBombardment.java @@ -37,6 +37,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -54,15 +55,14 @@ import mage.target.common.TargetCreatureOrPlayer; public class FieryBombardment extends CardImpl { public FieryBombardment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); // Chroma - {2}, Sacrifice a creature: Fiery Bombardment deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost. Effect effect = new FieryBombardmentEffect(); - effect.setText("Chroma - Fiery Bombardment deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent())); ability.addTarget(new TargetCreatureOrPlayer()); + ability.setAbilityWord(AbilityWord.CHROMA); this.addAbility(ability); } @@ -81,6 +81,7 @@ class FieryBombardmentEffect extends OneShotEffect { public FieryBombardmentEffect() { super(Outcome.Benefit); + staticText = "{this} deals damage to target creature or player equal to the number of red mana symbols in the sacrificed creature's mana cost."; } public FieryBombardmentEffect(final FieryBombardmentEffect effect) { @@ -117,4 +118,4 @@ class FieryBombardmentEffect extends OneShotEffect { } return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FireAtWill.java b/Mage.Sets/src/mage/cards/f/FireAtWill.java index 9185696458..182baebb8a 100644 --- a/Mage.Sets/src/mage/cards/f/FireAtWill.java +++ b/Mage.Sets/src/mage/cards/f/FireAtWill.java @@ -54,11 +54,10 @@ public class FireAtWill extends CardImpl { } public FireAtWill(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R/W}{R/W}{R/W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R/W}{R/W}{R/W}"); // Fire at Will deals 3 damage divided as you choose among one, two, or three target attacking or blocking creatures. - this.getSpellAbility().addEffect(new DamageMultiEffect(3)); + this.getSpellAbility().addEffect(new DamageMultiEffect(3).setText("{this} deals 3 damage divided as you choose among one, two, or three target attacking or blocking creatures.")); this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3, filter)); } diff --git a/Mage.Sets/src/mage/cards/g/GilderBairn.java b/Mage.Sets/src/mage/cards/g/GilderBairn.java index 0fadbc07bb..1ce8089546 100644 --- a/Mage.Sets/src/mage/cards/g/GilderBairn.java +++ b/Mage.Sets/src/mage/cards/g/GilderBairn.java @@ -52,7 +52,7 @@ import mage.target.TargetPermanent; public class GilderBairn extends CardImpl { public GilderBairn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}{G/U}"); this.subtype.add(SubType.OUPHE); this.power = new MageInt(1); @@ -80,7 +80,7 @@ class GilderBairnEffect extends OneShotEffect { public GilderBairnEffect() { super(Outcome.Benefit); - this.staticText = "For each counter on target permanent, put another of those counters on that permanent"; + this.staticText = "Double the number of each kind of counter on target permanent"; } public GilderBairnEffect(final GilderBairnEffect effect) { diff --git a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java index 82f91c5ec9..669c69b48f 100644 --- a/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java +++ b/Mage.Sets/src/mage/cards/g/GleamOfAuthority.java @@ -70,7 +70,9 @@ public class GleamOfAuthority extends CardImpl { // Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control DynamicValue amount = new CountersOnControlledCount(); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(amount, amount, Duration.WhileOnBattlefield) + .setText("Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control.") + )); // Enchanted creature has vigilance and "{W}, {T}: Bloster 1." ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA)); diff --git a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java index 0e273c06e0..2106d125af 100644 --- a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java +++ b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java @@ -64,10 +64,10 @@ public class GreenManaBattery extends CardImpl { Mana.GreenMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {G} to your mana pool, then add {G} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {G} to your mana pool, then add {G} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java index 5a5501bfb6..c4fe64e45a 100644 --- a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java +++ b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java @@ -50,7 +50,7 @@ import mage.counters.CounterType; */ public class HelixPinnacle extends CardImpl { - static final String rule = "if there are 100 or more tower counters on Helix Pinnacle, you win the game"; + static final String rule = "at the beginning of your upkeep, if there are 100 or more tower counters on Helix Pinnacle, you win the game"; public HelixPinnacle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); diff --git a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java index 089a13e108..87554db349 100644 --- a/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java +++ b/Mage.Sets/src/mage/cards/m/MerrowBonegnawer.java @@ -54,14 +54,14 @@ public class MerrowBonegnawer extends CardImpl { private UUID exileId = UUID.randomUUID(); - private static final FilterSpell filter = new FilterSpell("black spell"); + private static final FilterSpell filter = new FilterSpell("a black spell"); static { filter.add(new ColorPredicate(ObjectColor.BLACK)); } public MerrowBonegnawer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.ROGUE); diff --git a/Mage.Sets/src/mage/cards/m/Moonhold.java b/Mage.Sets/src/mage/cards/m/Moonhold.java index 9c559325df..1c10f6a44a 100644 --- a/Mage.Sets/src/mage/cards/m/Moonhold.java +++ b/Mage.Sets/src/mage/cards/m/Moonhold.java @@ -55,13 +55,13 @@ import mage.watchers.common.ManaSpentToCastWatcher; public class Moonhold extends CardImpl { public Moonhold(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R/W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R/W}"); // Target player can't play land cards this turn if {R} was spent to cast Moonhold and can't play creature cards this turn if {W} was spent to cast it. ContinuousRuleModifyingEffect effect = new MoonholdEffect(); ContinuousRuleModifyingEffect effect2 = new MoonholdEffect2(); - effect.setText("Target player can't play land cards this turn if {R} was spent to cast {this} "); - effect2.setText("and can't play creature cards this turn if {W} was spent to cast it."); + effect.setText("Target player can't play lands this turn if {R} was spent to cast {this}"); + effect2.setText("and can't cast creature spells this turn if {W} was spent to cast it."); this.getSpellAbility().addEffect(new ConditionalContinuousRuleModifyingEffect( effect, new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.R)))); @@ -69,7 +69,7 @@ public class Moonhold extends CardImpl { effect2, new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.W)))); this.getSpellAbility().addTarget(new TargetPlayer()); - this.getSpellAbility().addEffect(new InfoEffect("(Do both if {R}{W} was spent.)")); + this.getSpellAbility().addEffect(new InfoEffect(" (Do both if {R}{W} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); } diff --git a/Mage.Sets/src/mage/cards/n/NightskyMimic.java b/Mage.Sets/src/mage/cards/n/NightskyMimic.java index a0e1832e99..268d86b9ae 100644 --- a/Mage.Sets/src/mage/cards/n/NightskyMimic.java +++ b/Mage.Sets/src/mage/cards/n/NightskyMimic.java @@ -58,10 +58,10 @@ public class NightskyMimic extends CardImpl { filter.add(new ColorPredicate(ObjectColor.BLACK)); } - private String rule = "Whenever you cast a spell that's both white and black, {this} has base power and toughness 4/4 until end of turn and gains flying until end of turn"; + private String rule = "Whenever you cast a spell that's both white and black, {this} has base power and toughness 4/4 until end of turn and gains flying until end of turn."; public NightskyMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W/B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/B}"); this.subtype.add(SubType.SHAPESHIFTER); this.color.setBlack(true); diff --git a/Mage.Sets/src/mage/cards/p/PunctureBlast.java b/Mage.Sets/src/mage/cards/p/PunctureBlast.java index 3e6bfc161d..715e672a61 100644 --- a/Mage.Sets/src/mage/cards/p/PunctureBlast.java +++ b/Mage.Sets/src/mage/cards/p/PunctureBlast.java @@ -41,11 +41,12 @@ import mage.target.common.TargetCreatureOrPlayer; public class PunctureBlast extends CardImpl { public PunctureBlast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); this.addAbility(WitherAbility.getInstance()); this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + this.getSpellAbility().setRuleAtTheTop(false); } public PunctureBlast(final PunctureBlast card) { diff --git a/Mage.Sets/src/mage/cards/r/RedManaBattery.java b/Mage.Sets/src/mage/cards/r/RedManaBattery.java index 224f287c21..e661c11359 100644 --- a/Mage.Sets/src/mage/cards/r/RedManaBattery.java +++ b/Mage.Sets/src/mage/cards/r/RedManaBattery.java @@ -64,10 +64,10 @@ public class RedManaBattery extends CardImpl { Mana.RedMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {R} to your mana pool, then add {R} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {R} to your mana pool, then add {R} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RekindledFlame.java b/Mage.Sets/src/mage/cards/r/RekindledFlame.java index a9896973ca..c8fde66460 100644 --- a/Mage.Sets/src/mage/cards/r/RekindledFlame.java +++ b/Mage.Sets/src/mage/cards/r/RekindledFlame.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; import mage.cards.CardImpl; @@ -48,22 +48,25 @@ import mage.target.common.TargetCreatureOrPlayer; * @author jeffwadsworth */ public class RekindledFlame extends CardImpl { - + static final String rule = "if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand"; public RekindledFlame(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}"); // Rekindled Flame deals 4 damage to target creature or player. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); - + // At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand. - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new ConditionalOneShotEffect(new ReturnSourceFromGraveyardToHandEffect(), new OpponentHasNoCardsInHandCondition(), rule), TargetController.YOU, true); + Ability ability = new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), TargetController.YOU, true + ), + new OpponentHasNoCardsInHandCondition(), rule); ability.setRuleVisible(true); this.addAbility(ability); - + } public RekindledFlame(final RekindledFlame card) { @@ -91,4 +94,4 @@ class OpponentHasNoCardsInHandCondition implements Condition { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java index c1d7edba64..59a9c5f17b 100644 --- a/Mage.Sets/src/mage/cards/s/ScaleBlessing.java +++ b/Mage.Sets/src/mage/cards/s/ScaleBlessing.java @@ -51,11 +51,11 @@ import mage.players.Player; public class ScaleBlessing extends CardImpl { public ScaleBlessing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}"); // Bolster 1, then put a +1/+1 counter on each creature you control with a +1/+1 counter on it. Effect effect = new BolsterEffect(1); - effect.setText("Bolster 1"); + effect.setText("Bolster 1"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new ScaleBlessingEffect()); @@ -98,7 +98,7 @@ class ScaleBlessingEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { - for(Permanent permanent: game.getState().getBattlefield().getAllActivePermanents(filter , controller.getId(), game)) { + for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { permanent.addCounters(CounterType.P1P1.createInstance(), source, game); game.informPlayers(sourceObject.getName() + ": Put a +1/+1 counter on " + permanent.getLogName()); } diff --git a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java index 23e4341c3a..ac72bc7161 100644 --- a/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java +++ b/Mage.Sets/src/mage/cards/s/ShorecrasherMimic.java @@ -58,10 +58,10 @@ public class ShorecrasherMimic extends CardImpl { filter.add(new ColorPredicate(ObjectColor.BLUE)); } - private String rule = "Whenever you cast a spell that's both green and blue, {this} has base power and toughness 5/3 until end of turn and gains trample until end of turn"; + private String rule = "Whenever you cast a spell that's both green and blue, {this} has base power and toughness 5/3 until end of turn and gains trample until end of turn."; public ShorecrasherMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}"); this.subtype.add(SubType.SHAPESHIFTER); this.color.setBlue(true); diff --git a/Mage.Sets/src/mage/cards/t/TalarasBane.java b/Mage.Sets/src/mage/cards/t/TalarasBane.java index c89e8fb6a8..9715eeb33f 100644 --- a/Mage.Sets/src/mage/cards/t/TalarasBane.java +++ b/Mage.Sets/src/mage/cards/t/TalarasBane.java @@ -53,13 +53,12 @@ import mage.target.common.TargetOpponent; public class TalarasBane extends CardImpl { public TalarasBane(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal that creature card's toughness, then that player discards that card. this.getSpellAbility().addEffect(new TalarasBaneEffect()); this.getSpellAbility().addTarget(new TargetOpponent()); - + } public TalarasBane(final TalarasBane card) { @@ -73,9 +72,9 @@ public class TalarasBane extends CardImpl { } class TalarasBaneEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("a green or white creature card"); - + static { filter.add(Predicates.or( new ColorPredicate(ObjectColor.GREEN), @@ -85,7 +84,7 @@ class TalarasBaneEffect extends OneShotEffect { public TalarasBaneEffect() { super(Outcome.Detriment); - this.staticText = "Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal that creature card's toughness, then that player discards that card"; + this.staticText = "Target opponent reveals his or her hand. You choose a green or white creature card from it. You gain life equal to that creature card's toughness, then that player discards that card"; } public TalarasBaneEffect(final TalarasBaneEffect effect) { @@ -110,10 +109,10 @@ class TalarasBaneEffect extends OneShotEffect { } if (card != null) { int lifeGain = card.getToughness().getValue(); - you .gainLife(lifeGain, game); + you.gainLife(lifeGain, game); return targetPlayer.discard(card, source, game); } } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java index 9c6251028c..220e916e01 100644 --- a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java +++ b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java @@ -45,32 +45,31 @@ import mage.watchers.common.ManaSpentToCastWatcher; /** * * @author jeffwadsworth - + * */ public class UnnervingAssault extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control"); private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures you control"); - + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); filter2.add(new ControllerPredicate(TargetController.YOU)); } public UnnervingAssault(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U/R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U/R}"); // Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast Unnerving Assault, and creatures you control get +1/+0 until end of turn if {R} was spent to cast it. this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new BoostAllEffect(-1, 0, Duration.EndOfTurn, filter, false), - new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/0 until end of turn if {U} was spent to cast {this},")); + new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast {this},")); this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new BoostAllEffect(1, 0, Duration.EndOfTurn, filter2, false), - new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/0 until end of turn if {R} was spent to cast it")); + new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/+0 until end of turn if {R} was spent to cast it")); this.getSpellAbility().addEffect(new InfoEffect("(Do both if {U}{R} was spent.)")); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); - + } public UnnervingAssault(final UnnervingAssault card) { @@ -82,4 +81,3 @@ public class UnnervingAssault extends CardImpl { return new UnnervingAssault(this); } } - diff --git a/Mage.Sets/src/mage/cards/w/WakeThrasher.java b/Mage.Sets/src/mage/cards/w/WakeThrasher.java index 077a90acaa..b9f7be99fe 100644 --- a/Mage.Sets/src/mage/cards/w/WakeThrasher.java +++ b/Mage.Sets/src/mage/cards/w/WakeThrasher.java @@ -49,7 +49,7 @@ import mage.game.events.GameEvent.EventType; public class WakeThrasher extends CardImpl { public WakeThrasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.SOLDIER); @@ -57,7 +57,7 @@ public class WakeThrasher extends CardImpl { this.toughness = new MageInt(1); // Whenever a permanent you control becomes untapped, Wake Thrasher gets +1/+1 until end of turn. - this.addAbility(new BecomesUntappedControlledPermanentTriggeredAbility(new BoostSourceEffect(1,1, Duration.EndOfTurn), false)); + this.addAbility(new BecomesUntappedControlledPermanentTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false)); } @@ -71,7 +71,7 @@ public class WakeThrasher extends CardImpl { } } -class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilityImpl{ +class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilityImpl { public BecomesUntappedControlledPermanentTriggeredAbility(Effect effect, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); @@ -98,7 +98,7 @@ class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilit @Override public String getRule() { - return "When a permanent you control becomes untapped, " + super.getRule(); + return "Whenever a permanent you control becomes untapped, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/w/WardOfBones.java b/Mage.Sets/src/mage/cards/w/WardOfBones.java index 85058af51f..ca33b2b267 100644 --- a/Mage.Sets/src/mage/cards/w/WardOfBones.java +++ b/Mage.Sets/src/mage/cards/w/WardOfBones.java @@ -76,7 +76,9 @@ class WardOfBonesEffect extends ContinuousRuleModifyingEffectImpl { public WardOfBonesEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Each opponent who controls more creatures than you can't play creature cards. The same is true for artifacts, enchantments, and lands"; + staticText = "Each opponent who controls more creatures than you can't cast creature spells. " + + "The same is true for artifacts and enchantments.

" + + "Each opponent who controls more lands than you can't play lands."; } public WardOfBonesEffect(final WardOfBonesEffect effect) { diff --git a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java index 9e78d925f2..d2304d34b9 100644 --- a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java +++ b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java @@ -64,10 +64,10 @@ public class WhiteManaBattery extends CardImpl { Mana.WhiteMana(1), new IntPlusDynamicValue(1, new RemovedCountersForCostValue()), new TapSourceCost(), - "Add {W} to your mana pool, then add {W} to your mana pool for each storage counter removed this way", - true, new CountersSourceCount(CounterType.STORAGE)); - ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(), - "Remove any number of storage counters from {this}")); + "Add {W} to your mana pool, then add {W} to your mana pool for each charge counter removed this way", + true, new CountersSourceCount(CounterType.CHARGE)); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance(), + "Remove any number of charge counters from {this}")); this.addAbility(ability); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java index 5d6ec647d1..387bc7127e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java @@ -88,7 +88,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild", "Marath, Will of the Wild", StackClause.WHILE_NOT_ON_STACK); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Archangel of Thune"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, Remove X +1/+1 counters from Marath", "Archangel of Thune"); setChoice(playerA, "X=3"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player @@ -132,7 +132,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Elesh Norn, Grand Cenobite"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, Remove X +1/+1 counters from Marath", "Elesh Norn, Grand Cenobite"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player setChoice(playerA, "X=1"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java index 4d9ad42869..058c8787f8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java @@ -273,7 +273,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); setStopAt(2, PhaseStep.BEGIN_COMBAT); @@ -309,7 +309,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{5}{G}: Turn"); @@ -353,7 +353,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); addTarget(playerB, "Silvercoat Lion"); setStopAt(2, PhaseStep.END_TURN); @@ -431,7 +431,7 @@ public class ManifestTest extends CardTestPlayerBase { skipInitShuffling(); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature"); setChoice(playerB, "Silvercoat Lion"); activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice a creature"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java index b57d4b3c5a..9f25fe66a1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java @@ -82,7 +82,7 @@ public class SuspendTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Jhoira of the Ghitu", 1); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend"); setChoice(playerA, "Silvercoat Lion"); setStopAt(11, PhaseStep.PRECOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java index 23cf48dd18..9d950e8a0f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/ExileAndReturnTest.java @@ -53,7 +53,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tawnos's Coffin"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}", "Silvercoat Lion"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -83,7 +83,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tawnos's Coffin"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Battlegrowth", "Silvercoat Lion"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}", "Silvercoat Lion"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}", "Silvercoat Lion"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -123,7 +123,7 @@ public class ExileAndReturnTest extends CardTestPlayerBase { castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Battlegrowth", "Bramble Elemental"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Blanchwood Armor", "Bramble Elemental"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frog Tongue", "Bramble Elemental"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}", "Bramble Elemental"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}", "Bramble Elemental"); setStopAt(3, PhaseStep.PRECOMBAT_MAIN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java index 2ca85699eb..f1e1a6900f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/sacrifice/TradingPostTest.java @@ -59,7 +59,7 @@ public class TradingPostTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Act of Treason", "Savannah Lions"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},{T}, Sacrifice a creature", "Helm of Possession", "Act of Treason", StackClause.WHILE_NOT_ON_STACK); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, {T}, Sacrifice a creature", "Helm of Possession", "Act of Treason", StackClause.WHILE_NOT_ON_STACK); setChoice(playerA, "Savannah Lions"); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java index 32387a9896..d180cdadf6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java @@ -185,7 +185,7 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { // {3}, {T}: Rod of Ruin deals 1 damage to target creature or player. addCard(Zone.BATTLEFIELD, playerA, "Rod of Ruin", 1); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java index b5acc76e54..e5ce6a0800 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/AngelOfJubilationTest.java @@ -82,7 +82,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Island", 4); addCard(Zone.BATTLEFIELD, playerB, "Food Chain"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2},Sacrifice a permanent you control: Return target creature to its owner's hand."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand."); playerB.addChoice("Food Chain"); playerA.addTarget("Angel of Jubilation"); @@ -100,7 +100,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk"); addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves", 2); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2},Sacrifice a permanent you control: Return target creature to its owner's hand."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand."); playerB.addChoice("Nantuko Husk"); playerA.addTarget("Angel of Jubilation"); @@ -151,7 +151,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tomb of Urami"); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}, Sacrifice all lands you control: Create a legendary 5/5 black Demon Spirit creature token with flying named Urami."); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}, Sacrifice all lands you control: Create a legendary 5/5 black Demon Spirit creature token with flying named Urami."); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java index 1e19212192..ceed83b997 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SerraAscendantTest.java @@ -69,7 +69,7 @@ public class SerraAscendantTest extends CardTestPlayerBase { playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains"); castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Martyr of Sands"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},You may reveal X white cards from your hand"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, You may reveal X white cards from your hand"); setChoice(playerA,"X=3"); attack(3, playerA, "Serra Ascendant"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java index 9eba9d61cb..038f5665e8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExchangeControlTest.java @@ -214,7 +214,7 @@ public class ExchangeControlTest extends CardTestPlayerBase { addTarget(playerA, "Manta Riders"); // now use the activated ability to make the "Silvercoat Lions" (that became Mana Riders) flying - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}: {this} gains Flying until end of turn."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}: {this} gains flying until end of turn."); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java index f6cf2fd3f1..2246c955a1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlDiedCastAgainTest.java @@ -100,7 +100,7 @@ public class GainControlDiedCastAgainTest extends CardTestPlayerBase { castSpell(4, PhaseStep.POSTCOMBAT_MAIN, playerB, "Akroma's Vengeance"); // Put Elesh Norn back on library - activateAbility(5, PhaseStep.END_TURN, playerB, "{1}{B},{T}: Put target creature card", "Elesh Norn, Grand Cenobite"); + activateAbility(5, PhaseStep.END_TURN, playerB, "{1}{B}, {T}: Put target creature card", "Elesh Norn, Grand Cenobite"); castSpell(6, PhaseStep.PRECOMBAT_MAIN, playerB, "Elesh Norn, Grand Cenobite"); setStopAt(6, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java index 075d4f1ac0..3a169d8f9d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/GainControlTargetEffectTest.java @@ -60,10 +60,10 @@ public class GainControlTargetEffectTest extends CardTestPlayerBase { // Persist (When this creature dies, if it had no -1/-1 counters on it, return it to the battlefield under its owner's control with a -1/-1 counter on it.) addCard(Zone.BATTLEFIELD, playerB, "Glen Elendra Archmage"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as {this} remains tapped.", "Glen Elendra Archmage"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as {this} remains tapped.", "Glen Elendra Archmage"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Strike", playerA); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U},Sacrifice {this}: Counter target noncreature spell.", "Lightning Strike"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}, Sacrifice {this}: Counter target noncreature spell.", "Lightning Strike"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -94,7 +94,7 @@ public class GainControlTargetEffectTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Mutavault", 1); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}: Until end of turn {this} becomes"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}: Gain control", "Mutavault"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}: Gain control", "Mutavault"); setChoice(playerA, "No"); // Don't untap the Shackles setStopAt(3, PhaseStep.PRECOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java index 103c8848bb..893bd4fd0d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/WillbreakerTest.java @@ -60,7 +60,7 @@ public class WillbreakerTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B},Remove", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Remove", "Silvercoat Lion"); setChoice(playerA, "X=0"); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java index d157967cb5..29f0bf95f4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/FeldonOfTheThirdPathTest.java @@ -58,7 +58,7 @@ public class FeldonOfTheThirdPathTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, - "{2}{R},{T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", + "{2}{R}, {T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", "Highway Robber"); setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); execute(); @@ -82,7 +82,7 @@ public class FeldonOfTheThirdPathTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, - "{2}{R},{T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", + "{2}{R}, {T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types. It gains haste. Sacrifice it at the beginning of the next end step.", "Sepulchral Primordial"); addTarget(playerA, "Silvercoat Lion"); // target for ETB Sepulchral Primordial setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java index 2036f56dc2..8369719040 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java @@ -71,7 +71,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Lightning Bolt"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}:"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); @@ -93,7 +93,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Lightning Bolt"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2},{T}:"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "No"); @@ -136,7 +136,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { attack(2, playerB, "Dross Crocodile"); attack(2, playerB, "Dross Crocodile"); - activateAbility(2, PhaseStep.DECLARE_BLOCKERS, playerA, "{2},{T}:"); + activateAbility(2, PhaseStep.DECLARE_BLOCKERS, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); @@ -180,7 +180,7 @@ public class IsochronScepterTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter"); addTarget(playerA, "Silence"); - activateAbility(2, PhaseStep.UPKEEP, playerA, "{2},{T}:"); + activateAbility(2, PhaseStep.UPKEEP, playerA, "{2}, {T}:"); setChoice(playerA, "Yes"); setChoice(playerA, "Yes"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java index 9004e3a81a..b708a3d6c9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/MimicVatTest.java @@ -63,10 +63,10 @@ public class MimicVatTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clone"); setChoice(playerA, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice a creature"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature"); setChoice(playerA, "Yes"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}: Create a token"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}: Create a token"); setChoice(playerA, "Silvercoat Lion"); setStopAt(3, PhaseStep.BEGIN_COMBAT); @@ -95,10 +95,10 @@ public class MimicVatTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph"); setChoice(playerA, "Yes"); setChoice(playerA, "Silvercoat Lion"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice a creature"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice a creature"); setChoice(playerA, "Yes"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}: Create a token that's a copy of a card exiled with "); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}: Create a token that's a copy of a card exiled with "); setChoice(playerA, "Yes"); setChoice(playerA, "Silvercoat Lion"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java index 96f73b57b8..d2650054c7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RemoveCounterCostTest.java @@ -48,7 +48,7 @@ public class RemoveCounterCostTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Novijen Sages"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},Remove two +1/+1 counters"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, Remove two +1/+1 counters"); setChoice(playerA, "X=2"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java index 9310dcbf95..f33ff1c4fb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/HeartstoneTest.java @@ -54,7 +54,7 @@ public class HeartstoneTest extends CardTestPlayerBase { addCard(Zone.HAND, playerB, "Lightning Bolt"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U},Tap two untapped Wizards you control: Copy target instant or sorcery spell. You may choose new targets for the copy.", "Lightning Bolt"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{U}, Tap two untapped Wizards you control: Copy target instant or sorcery spell. You may choose new targets for the copy.", "Lightning Bolt"); setChoice(playerA, "Yes"); addTarget(playerA, playerB); setStopAt(1, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java index 2d00ce3f91..71ea880114 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/SkullclampTest.java @@ -69,7 +69,7 @@ public class SkullclampTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Silvercoat Lion"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X},Sacrifice"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X}, Sacrifice"); setChoice(playerB, "X=2"); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java index 4c68018520..104cebecbf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java @@ -128,7 +128,7 @@ public class ConditionalManaTest extends CardTestPlayerBase { activateManaAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: Add {C}{C}{C}{C}"); - activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X},{T}: Untap"); + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X}, {T}: Untap"); setChoice(playerB, "X=4"); addTarget(playerB, "Island"); addTarget(playerB, "Island"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java index b178bc6472..54f9684f2e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/CryptGhastTest.java @@ -84,7 +84,7 @@ public class CryptGhastTest extends CardTestPlayerBase { // {X}{U}{R},{T}: Nin, the Pain Artist deals X damage to target creature. That creature's controller draws X cards. addCard(Zone.BATTLEFIELD, playerB, "Nin, the Pain Artist", 1); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{X}{U}{R},{T}: {this} deals X damage to target creature", "Crypt Ghast"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{X}{U}{R}, {T}: {this} deals X damage to target creature", "Crypt Ghast"); setChoice(playerB, "X=2"); // Crypt Ghast may no longer give additional mana diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java index 19b042b09d..e5d467026c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/DoublingCubeTest.java @@ -1,12 +1,10 @@ package org.mage.test.cards.mana; -import mage.abilities.costs.mana.ColorlessManaCost; import mage.constants.ManaType; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; -import org.mage.test.serverside.base.impl.CardTestAPIImpl; public class DoublingCubeTest extends CardTestPlayerBase { @@ -26,18 +24,16 @@ public class DoublingCubeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, cube); addCard(Zone.BATTLEFIELD, playerA, upwelling); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G} to your mana pool"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {C}{C}"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3},{T}:"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}, {T}:"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); assertManaPool(playerA, ManaType.COLORLESS, 4); - } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java index 48ce51cda9..f03c021f1c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java @@ -52,8 +52,8 @@ public class HarvesterDruidTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 2 red and 1 blue mana", "{R}{R}{U}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{R}{U}{U}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 2 red and 1 blue mana", "{U}{R}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{R}", options.get(1).toString()); } @Test @@ -68,9 +68,9 @@ public class HarvesterDruidTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 3 red and 1 blue mana", "{R}{R}{R}{U}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{R}{R}{U}{U}", options.get(1).toString()); - Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{R}{R}{U}{U}", options.get(2).toString()); - Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{R}{U}{U}{U}", options.get(3).toString()); + Assert.assertEquals("Player should be able to create 3 red and 1 blue mana", "{U}{R}{R}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 2 red and 2 blue mana", "{U}{U}{R}{R}", options.get(2).toString()); + Assert.assertEquals("Player should be able to create 1 red and 3 blue mana", "{U}{U}{U}{R}", options.get(3).toString()); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java index 2c7a35b08c..29df140553 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java @@ -52,7 +52,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool. addCard(Zone.BATTLEFIELD, playerA, "Omnath, Locus of Mana", 1); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); @@ -75,12 +75,12 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool. addCard(Zone.BATTLEFIELD, playerA, "Omnath, Locus of Mana", 1); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); @@ -106,12 +106,12 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // If unused mana would empty from your mana pool, that mana becomes colorless instead. addCard(Zone.BATTLEFIELD, playerA, "Kruphix, God of Horizons", 1); // 1 G devotion - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -143,7 +143,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cackling Counterpart"); addTarget(playerA, "Simic Guildmage"); - activateManaAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -205,7 +205,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2); // two colorless to pay for nykthos addCard(Zone.HAND, playerA, pObliterator); // just for something to cast for 4 black mana - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Black"); // should produce 4 black mana castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pObliterator); // costs exactly 4 black mana should be castable diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java index 862b036a30..8479228d8b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java @@ -174,13 +174,13 @@ public class ReflectingPoolTest extends CardTestPlayerBase { ManaOptions options = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("Player A should be able to create the ", "{G}{G}{G}", options.get(0).toString()); - Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(1).toString()); - Assert.assertEquals("Player A should be able to create the ", "{G}{G}{W}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet - Assert.assertEquals("Player A should be able to create the ", "{G}{W}{W}", options.get(3).toString()); + Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(1).toString()); + Assert.assertEquals("Player A should be able to create the ", "{W}{G}{G}", options.get(2).toString()); // ManaOption type optimzing seems not optimal yet + Assert.assertEquals("Player A should be able to create the ", "{W}{W}{G}", options.get(3).toString()); Assert.assertEquals("Player A should be able to create only 3 different mana options", 4, options.size()); options = playerB.getAvailableManaTest(currentGame); - Assert.assertEquals("Player B should be able to create the ", "{G}{W}", options.get(0).toString()); + Assert.assertEquals("Player B should be able to create the ", "{W}{G}", options.get(0).toString()); Assert.assertEquals("Player B should be able to create the ", "{W}{W}", options.get(1).toString()); Assert.assertEquals("Player B should be able to create only 3 different mana options", 2, options.size()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java index be7cc9427c..3c6fce6f11 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java @@ -70,8 +70,8 @@ public class SylvokExplorerTest extends CardTestPlayerBase { execute(); ManaOptions options = playerA.getAvailableManaTest(currentGame); - Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{R}{W}", options.get(0).toString()); - Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{U}{W}", options.get(1).toString()); + Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{W}{R}", options.get(0).toString()); + Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{W}{U}", options.get(1).toString()); } @Test diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java index eea4e061a7..56e6ce1d86 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/GrindstoneTest.java @@ -37,12 +37,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - public class GrindstoneTest extends CardTestPlayerBase { /** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Leaving one Progenius in play + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Leaving one Progenius in play */ @Test public void testGrindstoneProgenius() { @@ -61,19 +60,19 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - - Assert.assertEquals("Progenitus has to be in the libarary", 1, playerB.getLibrary().size()); + + Assert.assertEquals("Progenitus has to be in the libarary", 1, playerB.getLibrary().size()); assertPermanentCount(playerA, "Painter's Servant", 1); } - + /** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Iterating with two Progenius for a draw + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Iterating with two Progenius for a draw */ @Test public void testGrindstoneProgeniusDraw() { @@ -92,19 +91,19 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - + Assert.assertTrue("Has to be a draw because of endless iteration", currentGame.isADraw()); assertPermanentCount(playerA, "Painter's Servant", 1); } - -/** - * Tests that Grindstone mills all cards to graveyard while Painter's Servant is in play - * Iterating with two Progenius for a draw + + /** + * Tests that Grindstone mills all cards to graveyard while Painter's + * Servant is in play Iterating with two Progenius for a draw */ @Test public void testGrindstoneUlamog() { @@ -125,16 +124,14 @@ public class GrindstoneTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant"); setChoice(playerA, "Blue"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3},{T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Target player puts the top two cards of his or her library into his or her graveyard. If both cards share a color, repeat this process."); addTarget(playerA, playerB); setStopAt(1, PhaseStep.END_TURN); execute(); - + // No cards in graveyard because Ulamog shuffle all cards back to Lib assertGraveyardCount(playerB, 0); assertPermanentCount(playerA, "Painter's Servant", 1); - } + } } - - diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java index 9ef378862f..52168da7c8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/LeylineOfTheVoidTest.java @@ -59,7 +59,7 @@ public class LeylineOfTheVoidTest extends CardTestPlayerBase { // {X}, {T}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0. addCard(Zone.BATTLEFIELD, playerA, "Helm of Obedience"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},{T}: Target opponent puts cards", playerB); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, {T}: Target opponent puts cards", playerB); setChoice(playerA, "X=1"); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java index d9c413363f..6680c84977 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ZoneChangeReplacementTest.java @@ -332,7 +332,7 @@ public class ZoneChangeReplacementTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}: Return target creature", "Silvercoat Lion"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}: Return target creature", "Silvercoat Lion"); castSpell(2, PhaseStep.BEGIN_COMBAT, playerA, "Terror", "Silvercoat Lion"); setStopAt(2, PhaseStep.END_COMBAT); @@ -364,7 +364,7 @@ public class ZoneChangeReplacementTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerB, "Swamp", 5); addCard(Zone.GRAVEYARD, playerB, "Jace, Vryn's Prodigy"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B},{T}: Return target creature", "Jace, Vryn's Prodigy"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}{B}{B}, {T}: Return target creature", "Jace, Vryn's Prodigy"); // {T}: Draw a card, then discard a card. If there are five or more cards in your graveyard, exile Jace, Vryn's Prodigy, then return him to the battefield transformed under his owner's control. activateAbility(2, PhaseStep.BEGIN_COMBAT, playerB, "{T}: Draw a card, then discard a card. If there are five or more cards in your graveyard"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java index ff91ebf653..2b24a74680 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ContagionEngineTest.java @@ -85,7 +85,7 @@ public class ContagionEngineTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Contagion Engine"); addTarget(playerA, playerB); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4},{T}: Proliferate"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}, {T}: Proliferate"); setChoice(playerA, "Wall of Frost^Kalonian Behemoth^Plated Slagwurm^Teysa, Envoy of Ghosts^Ajani Goldmane"); setChoice(playerA, "Wall of Frost^Kalonian Behemoth^Plated Slagwurm^Teysa, Envoy of Ghosts^Ajani Goldmane"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java index bc6de56293..9f931fbd17 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/MagewrightStoneTest.java @@ -17,7 +17,7 @@ public class MagewrightStoneTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, meanderer, 1, true); addCard(Zone.BATTLEFIELD, playerA, magewrightStone); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},{T}: Untap target creature", meanderer); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, {T}: Untap target creature", meanderer); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java index 09a5327a48..59aae8be99 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/SoulFoundryTest.java @@ -53,7 +53,7 @@ public class SoulFoundryTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Foundry"); setChoice(playerA, "Yes"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},{T}: Create a token"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X}, {T}: Create a token"); setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java index 0484faccaa..8069e2d2e1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java @@ -12,7 +12,7 @@ public class GrinningTotemTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); addCard(Zone.BATTLEFIELD, playerA, "Grinning Totem"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); setStopAt(3, PhaseStep.BEGIN_COMBAT); execute(); @@ -28,7 +28,7 @@ public class GrinningTotemTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tormod's Crypt"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}, Sacrifice {this}: Exile all cards", playerA); setStopAt(3, PhaseStep.BEGIN_COMBAT); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java index 7f90d651e3..6cf97093b4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTheTargetTest.java @@ -52,7 +52,7 @@ public class BecomesTheTargetTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P},{T}: Tap target creature", "Silvercoat Lion"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P}, {T}: Tap target creature", "Silvercoat Lion"); setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java index d342098352..28ca2c83e0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SpellskiteTest.java @@ -97,7 +97,7 @@ public class SpellskiteTest extends CardTestPlayerBase { // Whenever Frost Titan enters the battlefield or attacks, tap target permanent. It doesn't untap during its controller's next untap step. addCard(Zone.HAND, playerB, "Frost Titan", 1); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Gain control", "Spellskite"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Gain control", "Spellskite"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frost Titan"); addTarget(playerB, "Silvercoat Lion"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java index 160f68428f..01a5e9eb1b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/FellShepherdTest.java @@ -29,7 +29,7 @@ public class FellShepherdTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Fell Shepherd"); playerA.addChoice("Craw Wurm"); - activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{B},Sacrifice another creature: Target creature gets -2/-2 until end of turn.", "Raging Goblin"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Sacrifice another creature: Target creature gets -2/-2 until end of turn.", "Raging Goblin"); attack(3, playerA, "Fell Shepherd"); setStopAt(3, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java index 0bcc381376..1569a8ec8d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BloodchiefAscensionTest.java @@ -172,7 +172,7 @@ public class BloodchiefAscensionTest extends CardTestMultiPlayerBase { addCard(Zone.HAND, playerB, "Bellows Lizard", 5); // Player order: A -> D -> C -> B - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerD, "{U},{T}: Each player discards"); + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerD, "{U}, {T}: Each player discards"); setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java index 08c6b54f2f..6c11c32730 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/cards/abilities/ProtectionFromTypeTest.java @@ -17,7 +17,7 @@ public class ProtectionFromTypeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Tel-Jilad Fallen"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a charge counter from {this}, {T}: put a -1/-1 counter on target creature.", "Tel-Jilad Fallen"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Remove a charge counter from {this}, {T}: put a -1/-1 counter on target creature.", "Tel-Jilad Fallen"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -32,7 +32,7 @@ public class ProtectionFromTypeTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Coral Merfolk"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a charge counter from {this}, {T}: Put a -1/-1 counter on target creature.", "Coral Merfolk"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Remove a charge counter from {this}, {T}: Put a -1/-1 counter on target creature.", "Coral Merfolk"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java index 0f45a8e717..91ea81bf86 100644 --- a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java @@ -72,9 +72,9 @@ public class ManaOptionsTest extends CardTestPlayerBase { Assert.assertEquals("mana variations don't fit", 4, manaOptions.size()); Assert.assertEquals("{G}{G}{G}", getManaOption(0, manaOptions)); - Assert.assertEquals("{R}{G}{G}{W}", getManaOption(1, manaOptions)); - Assert.assertEquals("{R}{R}{G}{W}{W}", getManaOption(2, manaOptions)); - Assert.assertEquals("{R}{R}{R}{W}{W}{W}", getManaOption(3, manaOptions)); + Assert.assertEquals("{W}{R}{G}{G}", getManaOption(1, manaOptions)); + Assert.assertEquals("{W}{W}{R}{R}{G}", getManaOption(2, manaOptions)); + Assert.assertEquals("{W}{W}{W}{R}{R}{R}", getManaOption(3, manaOptions)); } @@ -95,11 +95,11 @@ public class ManaOptionsTest extends CardTestPlayerBase { Assert.assertEquals("{C}{C}{W}", getManaOption(1, manaOptions)); Assert.assertEquals("{C}{C}{U}", getManaOption(2, manaOptions)); Assert.assertEquals("{C}{W}{W}", getManaOption(3, manaOptions)); - Assert.assertEquals("{C}{U}{W}", getManaOption(4, manaOptions)); + Assert.assertEquals("{C}{W}{U}", getManaOption(4, manaOptions)); Assert.assertEquals("{C}{U}{U}", getManaOption(5, manaOptions)); Assert.assertEquals("{W}{W}{W}", getManaOption(6, manaOptions)); - Assert.assertEquals("{U}{W}{W}", getManaOption(7, manaOptions)); - Assert.assertEquals("{U}{U}{W}", getManaOption(8, manaOptions)); + Assert.assertEquals("{W}{W}{U}", getManaOption(7, manaOptions)); + Assert.assertEquals("{W}{U}{U}", getManaOption(8, manaOptions)); Assert.assertEquals("{U}{U}{U}", getManaOption(9, manaOptions)); } @@ -151,7 +151,7 @@ public class ManaOptionsTest extends CardTestPlayerBase { ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); - Assert.assertEquals("{C}{G}{G}{W}{W}", getManaOption(0, manaOptions)); + Assert.assertEquals("{C}{W}{W}{G}{G}", getManaOption(0, manaOptions)); } // Crystal Quarry @@ -169,8 +169,8 @@ public class ManaOptionsTest extends CardTestPlayerBase { ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); Assert.assertEquals("mana variations don't fit", 2, manaOptions.size()); - Assert.assertEquals("{C}{G}{G}{G}{W}{W}", getManaOption(0, manaOptions)); - Assert.assertEquals("{R}{G}{U}{W}{B}", getManaOption(1, manaOptions)); + Assert.assertEquals("{C}{W}{W}{G}{G}{G}", getManaOption(0, manaOptions)); + Assert.assertEquals("{W}{U}{B}{R}{G}", getManaOption(1, manaOptions)); } // Nykthos, Shrine to Nyx diff --git a/Mage/src/main/java/mage/abilities/Abilities.java b/Mage/src/main/java/mage/abilities/Abilities.java index 2e4c629a2c..d0425f6fd7 100644 --- a/Mage/src/main/java/mage/abilities/Abilities.java +++ b/Mage/src/main/java/mage/abilities/Abilities.java @@ -61,6 +61,8 @@ public interface Abilities extends List, Serializable { */ List getRules(String source); + List getRules(String source, boolean capitalize); + /** * Retrieves all activated abilities for the given {@link Zone}. * diff --git a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java index 7a1dfba19d..a7a10a3236 100644 --- a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java @@ -69,6 +69,11 @@ public class AbilitiesImpl extends ArrayList implements Ab @Override public List getRules(String source) { + return getRules(source, true); + } + + @Override + public List getRules(String source, boolean capitalize) { List rules = new ArrayList<>(); for (T ability : this) { @@ -78,7 +83,9 @@ public class AbilitiesImpl extends ArrayList implements Ab if (!(ability instanceof SpellAbility || ability instanceof PlayLandAbility)) { String rule = ability.getRule(); if (rule != null && rule.length() > 3) { - rule = Character.toUpperCase(rule.charAt(0)) + rule.substring(1); + if (capitalize) { + rule = Character.toUpperCase(rule.charAt(0)) + rule.substring(1); + } if (ability.getRuleAtTheTop()) { rules.add(0, rule); } else { diff --git a/Mage/src/main/java/mage/abilities/CompoundAbility.java b/Mage/src/main/java/mage/abilities/CompoundAbility.java index d122735f84..e07d934980 100644 --- a/Mage/src/main/java/mage/abilities/CompoundAbility.java +++ b/Mage/src/main/java/mage/abilities/CompoundAbility.java @@ -31,7 +31,7 @@ public class CompoundAbility extends AbilitiesImpl { } StringBuilder sb = new StringBuilder(); - List rules = super.getRules(null); + List rules = super.getRules(null,false); for (int index = 0; index < rules.size(); index++) { if (index > 0) { if (index < rules.size() - 1) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java index 6f58c745bd..9eca132786 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import mage.constants.Outcome; @@ -38,6 +37,7 @@ import mage.target.common.TargetControlledPermanent; import java.util.List; import java.util.UUID; import mage.abilities.costs.Cost; +import mage.util.CardUtil; /** * @@ -49,7 +49,7 @@ public class UntapTargetCost extends CostImpl { public UntapTargetCost(TargetControlledPermanent target) { this.target = target; - this.text = "Untap " + target.getMaxNumberOfTargets() + ' ' + target.getTargetName(); + this.text = "Untap " + CardUtil.numberToText(target.getMaxNumberOfTargets(), "") + ' ' + target.getTargetName(); } public UntapTargetCost(final UntapTargetCost cost) { @@ -60,10 +60,11 @@ public class UntapTargetCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { if (target.choose(Outcome.Untap, controllerId, sourceId, game)) { - for (UUID targetId: (List)target.getTargets()) { + for (UUID targetId : (List) target.getTargets()) { Permanent permanent = game.getPermanent(targetId); - if (permanent == null) + if (permanent == null) { return false; + } paid |= permanent.untap(game); } } @@ -80,5 +81,4 @@ public class UntapTargetCost extends CostImpl { return new UntapTargetCost(this); } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java index 79bd6484f2..7ceebd0111 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/GetEmblemEffect.java @@ -46,7 +46,7 @@ public class GetEmblemEffect extends OneShotEffect { public GetEmblemEffect(Emblem emblem) { super(Outcome.Benefit); this.emblem = emblem; - this.staticText = "You get an emblem with \"" + +'"'; + this.staticText = getText(); } public GetEmblemEffect(final GetEmblemEffect effect) { @@ -74,7 +74,9 @@ public class GetEmblemEffect extends OneShotEffect { sb.append("You get an emblem with \""); List rules = emblem.getAbilities().getRules(null); if (rules.size() == 1) { - sb.append(rules.get(0)); + for (String s : rules) { + sb.append(s); + } sb.append('"'); } else if (rules.size() == 2) { for (String s : rules) { @@ -83,7 +85,6 @@ public class GetEmblemEffect extends OneShotEffect { } sb.append('"'); } - sb.append('.'); return sb.toString(); } } 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 b7e43315d5..5a93cbae46 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -264,9 +264,11 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff sb.append(". You may reveal "); sb.append(filter.getMessage()).append(" from among them and put it into your "); } else if (targetPickedCards == Zone.BATTLEFIELD) { - sb.append(". You "); + sb.append(". "); if (optional) { - sb.append("may "); + sb.append("You may p"); + } else { + sb.append('P'); } sb.append("put ").append(filter.getMessage()).append(" from among them onto the "); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index 1283cc5972..f622abea91 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -63,7 +63,7 @@ public class CantBlockAttachedEffect extends RestrictionEffect { sb.append(' ').append(filter.getMessage()); } if (duration == EndOfTurn) { - sb.append("this turn"); + sb.append(" this turn"); } else if (!duration.toString().isEmpty()) { sb.append(' ').append(duration.toString()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java index 796fa3060c..0de648e5bf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostEquippedEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.continuous; import mage.constants.Duration; @@ -116,21 +115,24 @@ public class BoostEquippedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("Equipped creature gets "); + sb.append("equipped creature gets "); String p = power.toString(); - if (!p.startsWith("-")) + if (!p.startsWith("-")) { sb.append('+'); + } sb.append(p).append('/'); String t = toughness.toString(); if (!t.startsWith("-")) { - if (p.startsWith("-")) + if (p.startsWith("-")) { sb.append('-'); - else + } else { sb.append('+'); + } } sb.append(t); - if (duration != Duration.WhileOnBattlefield) + if (duration != Duration.WhileOnBattlefield) { sb.append(' ').append(duration.toString()); + } String message = power.getMessage(); if (!message.isEmpty()) { sb.append(" for each "); diff --git a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java index 46471af292..5f1b480406 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ProtectionAbility.java @@ -89,7 +89,7 @@ public class ProtectionAbility extends StaticAbility { @Override public String getRule() { - return "protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); + return "Protection from " + filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove auras."); } public boolean canTarget(MageObject source, Game game) { diff --git a/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java b/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java index a88922d345..69381c0a15 100644 --- a/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/WitherAbility.java @@ -24,8 +24,7 @@ * 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.abilities.keyword; import mage.constants.Zone; @@ -37,19 +36,24 @@ import java.io.ObjectStreamException; /** * 702.77. Wither * - * 702.77a. Wither is a static ability. Damage dealt to a creature by a source with wither isn't marked on that creature. Rather, it causes that many -1/-1 counters to be put on that creature. See rule 119.3. + * 702.77a. Wither is a static ability. Damage dealt to a creature by a source + * with wither isn't marked on that creature. Rather, it causes that many -1/-1 + * counters to be put on that creature. See rule 119.3. * - * 702.77b. If a permanent leaves the battlefield before an effect causes it to deal damage, its last known information is used to determine whether it had wither. + * 702.77b. If a permanent leaves the battlefield before an effect causes it to + * deal damage, its last known information is used to determine whether it had + * wither. * - * 702.77c. The wither rules function no matter what zone an object with wither deals damage from. + * 702.77c. The wither rules function no matter what zone an object with wither + * deals damage from. * - * 702.77d. Multiple instances of wither on the same object are redundant. + * 702.77d. Multiple instances of wither on the same object are redundant. * - * @author nantuko + * @author nantuko */ public class WitherAbility extends StaticAbility implements MageSingleton { - private static final WitherAbility instance = new WitherAbility(); + private static final WitherAbility instance = new WitherAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -65,7 +69,7 @@ public class WitherAbility extends StaticAbility implements MageSingleton { @Override public String getRule() { - return "Wither (This deals damage to creatures in the form of -1/-1 counters.)"; + return "wither (This deals damage to creatures in the form of -1/-1 counters.)"; } @Override diff --git a/Mage/src/test/java/mage/ManaTest.java b/Mage/src/test/java/mage/ManaTest.java index 2f49626955..1ad59de468 100644 --- a/Mage/src/test/java/mage/ManaTest.java +++ b/Mage/src/test/java/mage/ManaTest.java @@ -497,7 +497,7 @@ public class ManaTest { String ret = mana.toString(); // then - assertEquals("{6}{R}{G}{G}{U}{U}{U}{B}{B}{B}{Any}{Any}", ret); + assertEquals("{6}{U}{U}{U}{B}{B}{B}{R}{G}{G}{Any}{Any}", ret); } @Test