From 5e1bc1e583c01b255c0297d56d15222cbbfaff18 Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Sun, 17 Jul 2016 17:01:11 -0700 Subject: [PATCH] implement Beasts of Bogardan also fixed Ivory Guardians to correctly boost other Ivory Guardians, and changed many similar cards to use OpponentControlsPermanentCondition instead of custom Conditions. --- .../sets/chronicles/BeastsOfBogardan.java | 88 +++++++++++++++++++ .../src/mage/sets/exodus/SkyshroudElite.java | 14 ++- .../src/mage/sets/iceage/BlackScarab.java | 33 +++---- .../src/mage/sets/iceage/BlueScarab.java | 31 ++----- .../src/mage/sets/iceage/GreenScarab.java | 33 +++---- Mage.Sets/src/mage/sets/iceage/RedScarab.java | 32 +++---- .../src/mage/sets/iceage/WhiteScarab.java | 31 ++----- .../mage/sets/innistrad/NightRevelers.java | 31 ++----- .../mage/sets/legends/BeastsOfBogardan.java | 52 +++++++++++ .../src/mage/sets/legends/IvoryGuardians.java | 43 ++++----- .../src/mage/sets/mirage/RadiantEssence.java | 8 +- .../sets/portalthreekingdoms/WuAdmiral.java | 15 +--- .../src/mage/sets/thedark/WaterWurm.java | 14 +-- .../cards/filters/IvoryGuardiansTest.java | 72 +++++++++++++++ 14 files changed, 294 insertions(+), 203 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/chronicles/BeastsOfBogardan.java create mode 100644 Mage.Sets/src/mage/sets/legends/BeastsOfBogardan.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/filters/IvoryGuardiansTest.java diff --git a/Mage.Sets/src/mage/sets/chronicles/BeastsOfBogardan.java b/Mage.Sets/src/mage/sets/chronicles/BeastsOfBogardan.java new file mode 100644 index 00000000000..509f6c81736 --- /dev/null +++ b/Mage.Sets/src/mage/sets/chronicles/BeastsOfBogardan.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.sets.chronicles; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.TokenPredicate; + +/** + * + * @author nigelzor + */ +public class BeastsOfBogardan extends CardImpl { + + private static final FilterCard protectionFilter = new FilterCard("red"); + private static final FilterPermanent controlFilter = new FilterPermanent("nontoken white permanent"); + + static { + protectionFilter.add(new ColorPredicate(ObjectColor.RED)); + controlFilter.add(new ColorPredicate(ObjectColor.WHITE)); + controlFilter.add(Predicates.not(new TokenPredicate())); + } + + public BeastsOfBogardan(UUID ownerId) { + super(ownerId, 45, "Beasts of Bogardan", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{R}"); + this.expansionSetCode = "CHR"; + this.subtype.add("Beast"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Protection from red + this.addAbility(new ProtectionAbility(protectionFilter)); + // Beasts of Bogardan gets +1/+1 as long as an opponent controls a nontoken white permanent. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(controlFilter), + "{this} gets +1/+1 as long as an opponent controls a nontoken white permanent"))); + } + + public BeastsOfBogardan(final BeastsOfBogardan card) { + super(card); + } + + @Override + public BeastsOfBogardan copy() { + return new BeastsOfBogardan(this); + } +} diff --git a/Mage.Sets/src/mage/sets/exodus/SkyshroudElite.java b/Mage.Sets/src/mage/sets/exodus/SkyshroudElite.java index 718847d5734..51d1dad8515 100644 --- a/Mage.Sets/src/mage/sets/exodus/SkyshroudElite.java +++ b/Mage.Sets/src/mage/sets/exodus/SkyshroudElite.java @@ -30,20 +30,17 @@ package mage.sets.exodus; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition.CountType; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SupertypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -55,7 +52,6 @@ public class SkyshroudElite extends CardImpl { static { filter.add(Predicates.not(new SupertypePredicate("Basic"))); - filter.add(new ControllerPredicate(TargetController.OPPONENT)); } public SkyshroudElite(UUID ownerId) { @@ -66,10 +62,10 @@ public class SkyshroudElite extends CardImpl { this.toughness = new MageInt(1); // Skyshroud Elite gets +1/+2 as long as an opponent controls a nonbasic land. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostSourceEffect(1, 2, Duration.WhileOnBattlefield), - new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0, false), - "{this} gets +1/+2 as long as an opponent controls a nonbasic land"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter), + "{this} gets +1/+2 as long as an opponent controls a nonbasic land"))); } public SkyshroudElite(final SkyshroudElite card) { diff --git a/Mage.Sets/src/mage/sets/iceage/BlackScarab.java b/Mage.Sets/src/mage/sets/iceage/BlackScarab.java index 3ced830ddc5..1d5b79d517e 100644 --- a/Mage.Sets/src/mage/sets/iceage/BlackScarab.java +++ b/Mage.Sets/src/mage/sets/iceage/BlackScarab.java @@ -27,12 +27,11 @@ */ package mage.sets.iceage; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -49,7 +48,6 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -60,9 +58,11 @@ import mage.target.common.TargetCreaturePermanent; public class BlackScarab extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("black creatures"); - + private static final FilterPermanent filter2 = new FilterPermanent("black permanent"); + static { filter.add(new ColorPredicate(ObjectColor.BLACK)); + filter2.add(new ColorPredicate(ObjectColor.BLACK)); } public BlackScarab(UUID ownerId) { @@ -70,21 +70,23 @@ public class BlackScarab extends CardImpl { this.expansionSetCode = "ICE"; this.subtype.add("Aura"); -// Enchant creature + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature can't be blocked by black creatures. Effect effect = new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); this.addAbility(ability); // Enchanted creature gets +2/+2 as long as an opponent controls a black permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), - new BlackScarabCondition(), "Enchanted creature gets +2/+2 as long as an opponent controls a black permanent"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter2), + "Enchanted creature gets +2/+2 as long as an opponent controls a black permanent"))); } public BlackScarab(final BlackScarab card) { @@ -96,18 +98,3 @@ public class BlackScarab extends CardImpl { return new BlackScarab(this); } } - -class BlackScarabCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new ColorPredicate(ObjectColor.BLACK)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/iceage/BlueScarab.java b/Mage.Sets/src/mage/sets/iceage/BlueScarab.java index f2d82c989c2..70fa5f44ebe 100644 --- a/Mage.Sets/src/mage/sets/iceage/BlueScarab.java +++ b/Mage.Sets/src/mage/sets/iceage/BlueScarab.java @@ -27,12 +27,11 @@ */ package mage.sets.iceage; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -49,7 +48,6 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -60,9 +58,11 @@ import mage.target.common.TargetCreaturePermanent; public class BlueScarab extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue creatures"); - + private static final FilterPermanent filter2 = new FilterCreaturePermanent("blue permanent"); + static { filter.add(new ColorPredicate(ObjectColor.BLUE)); + filter2.add(new ColorPredicate(ObjectColor.BLUE)); } public BlueScarab(UUID ownerId) { @@ -76,15 +76,17 @@ public class BlueScarab extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature can't be blocked by blue creatures. Effect effect = new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); this.addAbility(ability); // Enchanted creature gets +2/+2 as long as an opponent controls a blue permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), - new BlueScarabCondition(), "Enchanted creature gets +2/+2 as long as an opponent controls a blue permanent"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter2), + "Enchanted creature gets +2/+2 as long as an opponent controls a blue permanent"))); } public BlueScarab(final BlueScarab card) { @@ -96,18 +98,3 @@ public class BlueScarab extends CardImpl { return new BlueScarab(this); } } - -class BlueScarabCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new ColorPredicate(ObjectColor.BLUE)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/iceage/GreenScarab.java b/Mage.Sets/src/mage/sets/iceage/GreenScarab.java index d3d846e2ad5..870ba7c0f2f 100644 --- a/Mage.Sets/src/mage/sets/iceage/GreenScarab.java +++ b/Mage.Sets/src/mage/sets/iceage/GreenScarab.java @@ -27,12 +27,11 @@ */ package mage.sets.iceage; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -49,7 +48,6 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -60,9 +58,11 @@ import mage.target.common.TargetCreaturePermanent; public class GreenScarab extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures"); - + private static final FilterPermanent filter2 = new FilterPermanent("green permanent"); + static { filter.add(new ColorPredicate(ObjectColor.GREEN)); + filter2.add(new ColorPredicate(ObjectColor.GREEN)); } public GreenScarab(UUID ownerId) { @@ -70,21 +70,23 @@ public class GreenScarab extends CardImpl { this.expansionSetCode = "ICE"; this.subtype.add("Aura"); -// Enchant creature + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature can't be blocked by green creatures. Effect effect = new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); this.addAbility(ability); // Enchanted creature gets +2/+2 as long as an opponent controls a white permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), - new GreenScarabCondition(), "Enchanted creature gets +2/+2 as long as an opponent controls a green permanent"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter2), + "Enchanted creature gets +2/+2 as long as an opponent controls a green permanent"))); } public GreenScarab(final GreenScarab card) { @@ -96,18 +98,3 @@ public class GreenScarab extends CardImpl { return new GreenScarab(this); } } - -class GreenScarabCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new ColorPredicate(ObjectColor.GREEN)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/iceage/RedScarab.java b/Mage.Sets/src/mage/sets/iceage/RedScarab.java index 1cda24c5966..c5024752415 100644 --- a/Mage.Sets/src/mage/sets/iceage/RedScarab.java +++ b/Mage.Sets/src/mage/sets/iceage/RedScarab.java @@ -27,12 +27,11 @@ */ package mage.sets.iceage; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -49,7 +48,6 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -60,9 +58,11 @@ import mage.target.common.TargetCreaturePermanent; public class RedScarab extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red creatures"); - + private static final FilterPermanent filter2 = new FilterPermanent("red permanent"); + static { filter.add(new ColorPredicate(ObjectColor.RED)); + filter2.add(new ColorPredicate(ObjectColor.RED)); } public RedScarab(UUID ownerId) { @@ -70,21 +70,23 @@ public class RedScarab extends CardImpl { this.expansionSetCode = "ICE"; this.subtype.add("Aura"); -// Enchant creature + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature can't be blocked by red creatures. Effect effect = new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); this.addAbility(ability); // Enchanted creature gets +2/+2 as long as an opponent controls a red permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), - new RedScarabCondition(), "Enchanted creature gets +2/+2 as long as an opponent controls a red permanent"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter2), + "Enchanted creature gets +2/+2 as long as an opponent controls a red permanent"))); } public RedScarab(final RedScarab card) { @@ -97,17 +99,3 @@ public class RedScarab extends CardImpl { } } -class RedScarabCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new ColorPredicate(ObjectColor.RED)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} diff --git a/Mage.Sets/src/mage/sets/iceage/WhiteScarab.java b/Mage.Sets/src/mage/sets/iceage/WhiteScarab.java index 72429ccc8c1..8839581720e 100644 --- a/Mage.Sets/src/mage/sets/iceage/WhiteScarab.java +++ b/Mage.Sets/src/mage/sets/iceage/WhiteScarab.java @@ -27,12 +27,11 @@ */ package mage.sets.iceage; -import java.util.Set; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; @@ -49,7 +48,6 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -60,9 +58,11 @@ import mage.target.common.TargetCreaturePermanent; public class WhiteScarab extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creatures"); - + private static final FilterPermanent filter2 = new FilterPermanent("white permanent"); + static { filter.add(new ColorPredicate(ObjectColor.WHITE)); + filter2.add(new ColorPredicate(ObjectColor.WHITE)); } @@ -77,15 +77,17 @@ public class WhiteScarab extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature can't be blocked by white creatures. Effect effect = new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.AURA); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); this.addAbility(ability); // Enchanted creature gets +2/+2 as long as an opponent controls a white permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), - new WhiteScarabCondition(), "Enchanted creature gets +2/+2 as long as an opponent controls a white permanent"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield), + new OpponentControlsPermanentCondition(filter2), + "Enchanted creature gets +2/+2 as long as an opponent controls a white permanent"))); } public WhiteScarab(final WhiteScarab card) { @@ -97,18 +99,3 @@ public class WhiteScarab extends CardImpl { return new WhiteScarab(this); } } - -class WhiteScarabCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new ColorPredicate(ObjectColor.WHITE)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} diff --git a/Mage.Sets/src/mage/sets/innistrad/NightRevelers.java b/Mage.Sets/src/mage/sets/innistrad/NightRevelers.java index a00e1fed52e..650dc6a9aeb 100644 --- a/Mage.Sets/src/mage/sets/innistrad/NightRevelers.java +++ b/Mage.Sets/src/mage/sets/innistrad/NightRevelers.java @@ -27,23 +27,19 @@ */ package mage.sets.innistrad; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.constants.CardType; import mage.constants.Rarity; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.game.Game; -import java.util.Set; import java.util.UUID; -import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -51,7 +47,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class NightRevelers extends CardImpl { - private static final String rule = "{this} has haste as long as an opponent controls a Human."; + private static final FilterPermanent filter = new FilterPermanent("Human", "Human"); public NightRevelers(UUID ownerId) { super(ownerId, 153, "Night Revelers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{R}"); @@ -63,9 +59,10 @@ public class NightRevelers extends CardImpl { this.toughness = new MageInt(4); // Night Revelers has haste as long as an opponent controls a Human. - ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(HasteAbility.getInstance()), new NightRevelersCondition(), rule); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new GainAbilitySourceEffect(HasteAbility.getInstance()), + new OpponentControlsPermanentCondition(filter), + "{this} has haste as long as an opponent controls a Human."))); } public NightRevelers(final NightRevelers card) { @@ -77,19 +74,3 @@ public class NightRevelers extends CardImpl { return new NightRevelers(this); } } - -class NightRevelersCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(new SubtypePredicate("Human")); - - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/legends/BeastsOfBogardan.java b/Mage.Sets/src/mage/sets/legends/BeastsOfBogardan.java new file mode 100644 index 00000000000..6a8bf99075d --- /dev/null +++ b/Mage.Sets/src/mage/sets/legends/BeastsOfBogardan.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.legends; + +import java.util.UUID; + +/** + * + * @author nigelzor + */ +public class BeastsOfBogardan extends mage.sets.chronicles.BeastsOfBogardan { + + public BeastsOfBogardan(UUID ownerId) { + super(ownerId); + this.cardNumber = 133; + this.expansionSetCode = "LEG"; + } + + public BeastsOfBogardan(final BeastsOfBogardan card) { + super(card); + } + + @Override + public BeastsOfBogardan copy() { + return new BeastsOfBogardan(this); + } +} diff --git a/Mage.Sets/src/mage/sets/legends/IvoryGuardians.java b/Mage.Sets/src/mage/sets/legends/IvoryGuardians.java index fd2f952ff3e..35d8e9de689 100644 --- a/Mage.Sets/src/mage/sets/legends/IvoryGuardians.java +++ b/Mage.Sets/src/mage/sets/legends/IvoryGuardians.java @@ -27,13 +27,11 @@ */ package mage.sets.legends; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.keyword.ProtectionAbility; @@ -44,10 +42,11 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.Game; /** * @@ -55,14 +54,17 @@ import mage.game.Game; */ public class IvoryGuardians extends CardImpl { - private static final FilterCard filter = new FilterCard("red"); + private static final FilterCard protectionFilter = new FilterCard("red"); + private static final FilterPermanent controlFilter = new FilterPermanent("nontoken red permanent"); + private static final FilterCreaturePermanent boostFilter = new FilterCreaturePermanent(); static { - filter.add(new ColorPredicate(ObjectColor.RED)); + protectionFilter.add(new ColorPredicate(ObjectColor.RED)); + controlFilter.add(new ColorPredicate(ObjectColor.RED)); + controlFilter.add(Predicates.not(new TokenPredicate())); + boostFilter.add(new NamePredicate("Ivory Guardians")); } - private static final String rule = "Creatures named {this} get +1/+1 as long as an opponent controls a nontoken red permanent"; - public IvoryGuardians(UUID ownerId) { super(ownerId, 192, "Ivory Guardians", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); this.expansionSetCode = "LEG"; @@ -72,11 +74,12 @@ public class IvoryGuardians extends CardImpl { this.toughness = new MageInt(3); // Protection from red - this.addAbility(new ProtectionAbility(filter)); - + this.addAbility(new ProtectionAbility(protectionFilter)); // Creatures named Ivory Guardians get +1/+1 as long as an opponent controls a nontoken red permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostAllEffect(1, 1, Duration.WhileOnBattlefield), new IvoryGuardiansCondition(), rule))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, boostFilter, false), + new OpponentControlsPermanentCondition(controlFilter), + "Creatures named Ivory Guardians get +1/+1 as long as an opponent controls a nontoken red permanent"))); } public IvoryGuardians(final IvoryGuardians card) { @@ -88,19 +91,3 @@ public class IvoryGuardians extends CardImpl { return new IvoryGuardians(this); } } - -class IvoryGuardiansCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - boolean conditionApplies = false; - FilterPermanent filter = new FilterPermanent(); - filter.add(Predicates.not(new TokenPredicate())); - filter.add(new ColorPredicate(ObjectColor.RED)); - Set opponents = game.getOpponents(source.getControllerId()); - for (UUID opponentId : opponents) { - conditionApplies |= game.getBattlefield().countAll(filter, opponentId, game) > 0; - } - return conditionApplies; - } -} diff --git a/Mage.Sets/src/mage/sets/mirage/RadiantEssence.java b/Mage.Sets/src/mage/sets/mirage/RadiantEssence.java index 7135ab0b4f6..ed6ee431ab0 100644 --- a/Mage.Sets/src/mage/sets/mirage/RadiantEssence.java +++ b/Mage.Sets/src/mage/sets/mirage/RadiantEssence.java @@ -31,19 +31,16 @@ import java.util.UUID; import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition.CountType; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -55,7 +52,6 @@ public class RadiantEssence extends CardImpl { static { filter.add(new ColorPredicate(ObjectColor.BLACK)); - filter.add(new ControllerPredicate(TargetController.OPPONENT)); } public RadiantEssence(UUID ownerId) { @@ -68,7 +64,7 @@ public class RadiantEssence extends CardImpl { // Radiant Essence gets +1/+2 as long as an opponent controls a black permanent. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostSourceEffect(1, 2, Duration.WhileOnBattlefield), - new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0, false), + new OpponentControlsPermanentCondition(filter), "{this} gets +1/+2 as long as an opponent controls a black permanent"))); } diff --git a/Mage.Sets/src/mage/sets/portalthreekingdoms/WuAdmiral.java b/Mage.Sets/src/mage/sets/portalthreekingdoms/WuAdmiral.java index 9d732edec3a..abef94e1369 100644 --- a/Mage.Sets/src/mage/sets/portalthreekingdoms/WuAdmiral.java +++ b/Mage.Sets/src/mage/sets/portalthreekingdoms/WuAdmiral.java @@ -30,19 +30,15 @@ package mage.sets.portalthreekingdoms; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition.CountType; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -50,12 +46,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class WuAdmiral extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(); - - static { - filter.add(new SubtypePredicate("Island")); - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } + private static final FilterPermanent filter = new FilterPermanent("Island", "Island"); public WuAdmiral(UUID ownerId) { super(ownerId, 57, "Wu Admiral", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{U}"); @@ -68,7 +59,7 @@ public class WuAdmiral extends CardImpl { // Wu Admiral gets +1/+1 as long as an opponent controls an Island. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), - new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0, false), + new OpponentControlsPermanentCondition(filter), "{this} gets +1/+1 as long as an opponent controls an Island"))); } diff --git a/Mage.Sets/src/mage/sets/thedark/WaterWurm.java b/Mage.Sets/src/mage/sets/thedark/WaterWurm.java index 40679d9413b..108fa04edc4 100644 --- a/Mage.Sets/src/mage/sets/thedark/WaterWurm.java +++ b/Mage.Sets/src/mage/sets/thedark/WaterWurm.java @@ -30,18 +30,15 @@ package mage.sets.thedark; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -49,12 +46,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class WaterWurm extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(); - - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - filter.add(new SubtypePredicate("Island")); - } + private static final FilterPermanent filter = new FilterPermanent("Island", "Island"); public WaterWurm(UUID ownerId) { super(ownerId, 37, "Water Wurm", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{U}"); @@ -66,7 +58,7 @@ public class WaterWurm extends CardImpl { // Water Wurm gets +0/+1 as long as an opponent controls an Island. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( new BoostSourceEffect(0, 1, Duration.WhileOnBattlefield), - new PermanentsOnTheBattlefieldCondition(filter, PermanentsOnTheBattlefieldCondition.CountType.MORE_THAN, 0, false), + new OpponentControlsPermanentCondition(filter), "{this} gets +0/+1 as long as an opponent controls an Island"))); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/filters/IvoryGuardiansTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/filters/IvoryGuardiansTest.java new file mode 100644 index 00000000000..f805e9ca83d --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/filters/IvoryGuardiansTest.java @@ -0,0 +1,72 @@ +package org.mage.test.cards.filters; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author nigelzor + */ +public class IvoryGuardiansTest extends CardTestPlayerBase { + + @Test + public void testOneGuardian() { + addCard(Zone.BATTLEFIELD, playerA, "Goblin Hero"); + addCard(Zone.BATTLEFIELD, playerA, "Ivory Guardians"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Goblin Hero", 2, 2); + assertPowerToughness(playerA, "Ivory Guardians", 3, 3); + } + + @Test + public void testOneGuardianAndRedToken() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.HAND, playerA, "Dragon Fodder"); + addCard(Zone.BATTLEFIELD, playerB, "Ivory Guardians"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragon Fodder"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Goblin", 1, 1); + assertPowerToughness(playerB, "Ivory Guardians", 3, 3); + } + + @Test + public void testOneGuardianAndRedPermanent() { + addCard(Zone.BATTLEFIELD, playerA, "Goblin Hero"); + addCard(Zone.BATTLEFIELD, playerA, "Ivory Guardians"); + addCard(Zone.BATTLEFIELD, playerB, "Mons's Goblin Raiders"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Goblin Hero", 2, 2); + assertPowerToughness(playerA, "Ivory Guardians", 4, 4); + assertPowerToughness(playerB, "Mons's Goblin Raiders", 1, 1); + } + + @Test + public void testTwoGuardiansAndRedPermanent() { + addCard(Zone.BATTLEFIELD, playerA, "Goblin Hero"); + addCard(Zone.BATTLEFIELD, playerA, "Ivory Guardians"); + addCard(Zone.BATTLEFIELD, playerA, "Ivory Guardians"); + addCard(Zone.BATTLEFIELD, playerB, "Mons's Goblin Raiders"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Goblin Hero", 2, 2); + assertPowerToughness(playerA, "Ivory Guardians", 5, 5); + assertPowerToughness(playerB, "Mons's Goblin Raiders", 1, 1); + } + +}