diff --git a/Mage.Sets/src/mage/cards/d/DihadaBinderOfWills.java b/Mage.Sets/src/mage/cards/d/DihadaBinderOfWills.java index cdae2a4b16f..9ea7e36b145 100644 --- a/Mage.Sets/src/mage/cards/d/DihadaBinderOfWills.java +++ b/Mage.Sets/src/mage/cards/d/DihadaBinderOfWills.java @@ -1,21 +1,17 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.effects.common.RevealLibraryPickControllerEffect; -import mage.abilities.effects.common.UntapAllEffect; -import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.continuous.GainControlAllEffect; -import mage.abilities.keyword.HasteAbility; +import mage.abilities.effects.common.continuous.GainControlAllUntapGainHasteEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.Cards; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.*; import mage.filter.FilterCard; import mage.filter.StaticFilters; @@ -25,18 +21,20 @@ import mage.game.permanent.token.TreasureToken; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * @author Draya, awjackson */ public final class DihadaBinderOfWills extends CardImpl { - private static final FilterCreaturePermanent legendarycreaturefilter = new FilterCreaturePermanent("legendary creature"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("legendary creature"); static { - legendarycreaturefilter.add(SuperType.LEGENDARY.getPredicate()); + filter.add(SuperType.LEGENDARY.getPredicate()); } -public DihadaBinderOfWills(UUID ownerId, CardSetInfo setInfo) { + public DihadaBinderOfWills(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{R}{W}{B}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.DIHADA); @@ -53,7 +51,7 @@ public DihadaBinderOfWills(UUID ownerId, CardSetInfo setInfo) { ability.addEffect(new GainAbilityTargetEffect( IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn ).setText(", and indestructible until your next turn.")); - ability.addTarget(new TargetCreaturePermanent(0, 1, legendarycreaturefilter, false)); + ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); this.addAbility(ability); // -3: Reveal the top four cards of your library. @@ -62,16 +60,8 @@ public DihadaBinderOfWills(UUID ownerId, CardSetInfo setInfo) { this.addAbility(new LoyaltyAbility(new DihadaFilterEffect(), -3)); // -11: Gain control of all nonland permanents until end of turn. Untap them. They gain haste until end of turn. - ability = new LoyaltyAbility(new GainControlAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_PERMANENTS_NON_LAND), -11); - ability.addEffect(new UntapAllEffect(StaticFilters.FILTER_PERMANENTS_NON_LAND).setText("untap them")); - ability.addEffect(new GainAbilityAllEffect( - HasteAbility.getInstance(), - Duration.EndOfTurn, - StaticFilters.FILTER_PERMANENTS_NON_LAND, - "they gain haste until end of turn" - )); - this.addAbility(ability); - + this.addAbility(new LoyaltyAbility(new GainControlAllUntapGainHasteEffect(StaticFilters.FILTER_PERMANENTS_NON_LAND), -11)); + // Dihada, Binder of Wills can be your commander. this.addAbility(CanBeYourCommanderAbility.getInstance()); } @@ -94,7 +84,7 @@ class DihadaFilterEffect extends RevealLibraryPickControllerEffect { legendaryfilter.add(SuperType.LEGENDARY.getPredicate()); } - public DihadaFilterEffect() { + DihadaFilterEffect() { super(4, Integer.MAX_VALUE, legendaryfilter, PutCards.HAND, PutCards.GRAVEYARD, false); staticText = "Reveal the top four cards of your library. " + "Put any number of legendary cards from among them into your hand and the rest into your graveyard. " + diff --git a/Mage.Sets/src/mage/cards/m/MobRule.java b/Mage.Sets/src/mage/cards/m/MobRule.java index 85a3886064e..44e9b7f5715 100644 --- a/Mage.Sets/src/mage/cards/m/MobRule.java +++ b/Mage.Sets/src/mage/cards/m/MobRule.java @@ -1,23 +1,19 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Mode; -import mage.abilities.effects.common.UntapAllEffect; -import mage.abilities.effects.common.continuous.GainAbilityAllEffect; -import mage.abilities.effects.common.continuous.GainControlAllEffect; -import mage.abilities.keyword.HasteAbility; +import mage.abilities.effects.common.continuous.GainControlAllUntapGainHasteEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; -import mage.constants.Duration; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; +import java.util.UUID; + /** - * - * @author awjackson + * @author xenohedron */ public final class MobRule extends CardImpl { @@ -34,26 +30,10 @@ public final class MobRule extends CardImpl { // Choose one // Gain control of all creatures with power 4 or greater until end of turn. Untap those creatures. They gain haste until end of turn. - this.getSpellAbility().addEffect(new GainControlAllEffect(Duration.EndOfTurn, filter4orMore)); - this.getSpellAbility().addEffect(new UntapAllEffect(filter4orMore).setText("untap those creatures")); - this.getSpellAbility().addEffect(new GainAbilityAllEffect( - HasteAbility.getInstance(), - Duration.EndOfTurn, - filter4orMore, - "they gain haste until end of turn" - )); + this.getSpellAbility().addEffect(new GainControlAllUntapGainHasteEffect(filter4orMore).withTextOptions("those creatures")); // Gain control of all creatures with power 3 or less until end of turn. Untap those creatures. They gain haste until end of turn. - Mode mode = new Mode(new GainControlAllEffect(Duration.EndOfTurn, filter3orLess)); - mode.addEffect(new UntapAllEffect(filter3orLess).setText("untap those creatures")); - mode.addEffect(new GainAbilityAllEffect( - HasteAbility.getInstance(), - Duration.EndOfTurn, - filter3orLess, - "they gain haste until end of turn" - )); - - this.getSpellAbility().addMode(mode); + this.getSpellAbility().addMode(new Mode(new GainControlAllUntapGainHasteEffect(filter3orLess).withTextOptions("those creatures"))); } private MobRule(final MobRule card) { diff --git a/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java b/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java index 1048708ee47..53bc75ab66d 100644 --- a/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java +++ b/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java @@ -3,14 +3,11 @@ package mage.cards.r; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.UntapAllEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.continuous.GainControlAllEffect; +import mage.abilities.effects.common.continuous.GainControlAllUntapGainHasteEffect; import mage.abilities.keyword.FirstStrikeAbility; -import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -53,14 +50,7 @@ public final class RowanFearlessSparkmage extends CardImpl { this.addAbility(ability); // −9: Gain control of all creatures until end of turn. Untap them. They gain haste until end of turn. - ability = new LoyaltyAbility(new GainControlAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES), -9); - ability.addEffect(new UntapAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES).setText("untap them")); - ability.addEffect(new GainAbilityAllEffect( - HasteAbility.getInstance(), - Duration.EndOfTurn, - StaticFilters.FILTER_PERMANENT_CREATURES, - "they gain haste until end of turn" - )); + ability = new LoyaltyAbility(new GainControlAllUntapGainHasteEffect(StaticFilters.FILTER_PERMANENT_CREATURES), -9); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java index 54c41087386..bcbb71788cf 100644 --- a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java +++ b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java @@ -5,16 +5,12 @@ import mage.abilities.LoyaltyAbility; import mage.abilities.dynamicvalue.common.CardsInTargetHandCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.UntapAllEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.GainAbilityAllEffect; -import mage.abilities.effects.common.continuous.GainControlAllEffect; +import mage.abilities.effects.common.continuous.GainControlAllUntapGainHasteEffect; import mage.abilities.effects.common.discard.DiscardControllerEffect; -import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.StaticFilters; @@ -47,14 +43,7 @@ public final class TibaltTheFiendBlooded extends CardImpl { this.addAbility(ability); // -6: Gain control of all creatures until end of turn. Untap them. They gain haste until end of turn. - ability = new LoyaltyAbility(new GainControlAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES), -6); - ability.addEffect(new UntapAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES).setText("untap them")); - ability.addEffect(new GainAbilityAllEffect( - HasteAbility.getInstance(), - Duration.EndOfTurn, - StaticFilters.FILTER_PERMANENT_CREATURES, - "they gain haste until end of turn" - )); + ability = new LoyaltyAbility(new GainControlAllUntapGainHasteEffect(StaticFilters.FILTER_PERMANENT_CREATURES), -6); this.addAbility(ability); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/frf/MobRuleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/frf/MobRuleTest.java new file mode 100644 index 00000000000..8c303539877 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/frf/MobRuleTest.java @@ -0,0 +1,108 @@ +package org.mage.test.cards.single.frf; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class MobRuleTest extends CardTestPlayerBase { + + private static final String mobRule = "Mob Rule"; + /* Mob Rule {4}{R}{R} Sorcery + * Choose one — + * • Gain control of all creatures with power 4 or greater until end of turn. Untap those creatures. They gain haste until end of turn. + * • Gain control of all creatures with power 3 or less until end of turn. Untap those creatures. They gain haste until end of turn. + */ + + private static final String lord = "Merfolk Sovereign"; // 2/2 + /* Merfolk Sovereign {1}{U}{U} Creature — Merfolk Noble + * Other Merfolk creatures you control get +1/+1. + * {T}: Target Merfolk creature can’t be blocked this turn. + */ + + private static final String smog = "Smog Elemental"; // 3/3 + /* Smog Elemental {4}{B}{B} Creature — Elemental + * Flying + * Creatures with flying your opponents control get -1/-1. + */ + + private static final String bond = "Bond of Discipline"; + // {4}{W} Tap all creatures your opponents control. Creatures you control gain lifelink until end of turn. + + private static final String merfolk1 = "Merfolk of the Pearl Trident"; // 1/1 merfolk + private static final String merfolk2 = "Coral Merfolk"; // 2/1 merfolk + private static final String merfolk3 = "Coral Commando"; // 3/2 merfolk + private static final String serra = "Serra Angel"; // 4/4 flying vigilance + private static final String vizzerdrix = "Vizzerdrix"; // 6/6 + + @Test + public void testMobRuleSmall() { + addCard(Zone.HAND, playerA, mobRule); + addCard(Zone.HAND, playerA, bond); + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 11); + addCard(Zone.BATTLEFIELD, playerA, smog); + addCard(Zone.BATTLEFIELD, playerB, lord); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk1); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk2); // 3/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk3); // 4/3 + addCard(Zone.BATTLEFIELD, playerB, serra); // 3/3 + addCard(Zone.BATTLEFIELD, playerB, vizzerdrix); // 6/6 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bond); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mobRule); + setModeChoice(playerA, "2"); // power 3 or less + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, 2); + assertPowerToughness(playerA, smog, 3, 3); + assertPowerToughness(playerA, lord, 2, 2); + assertPowerToughness(playerA, merfolk1, 2, 2); + assertPowerToughness(playerA, merfolk2, 3, 2); + assertPowerToughness(playerB, merfolk3, 3, 2); + assertTapped(merfolk3, true); + assertPowerToughness(playerA, serra, 4, 4); + assertTapped(serra, false); + assertPowerToughness(playerB, vizzerdrix, 6, 6); + } + + + @Test + public void testMobRuleBig() { + addCard(Zone.HAND, playerA, mobRule); + addCard(Zone.HAND, playerA, bond); + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 11); + addCard(Zone.BATTLEFIELD, playerA, smog); + addCard(Zone.BATTLEFIELD, playerB, lord); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk1); // 2/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk2); // 3/2 + addCard(Zone.BATTLEFIELD, playerB, merfolk3); // 4/3 + addCard(Zone.BATTLEFIELD, playerB, serra); // 3/3 + addCard(Zone.BATTLEFIELD, playerB, vizzerdrix); // 6/6 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bond); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mobRule); + setModeChoice(playerA, "1"); // power 4 or greater + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, 2); + assertPowerToughness(playerA, smog, 3, 3); + assertPowerToughness(playerB, lord, 2, 2); + assertPowerToughness(playerB, merfolk1, 2, 2); + assertPowerToughness(playerB, merfolk2, 3, 2); + assertPowerToughness(playerA, merfolk3, 3, 2); + assertTapped(merfolk3, false); + assertPowerToughness(playerB, serra, 3, 3); + assertPowerToughness(playerA, vizzerdrix, 6, 6); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllUntapGainHasteEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllUntapGainHasteEffect.java new file mode 100644 index 00000000000..5aade80fd9c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlAllUntapGainHasteEffect.java @@ -0,0 +1,67 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.UntapAllEffect; +import mage.abilities.keyword.HasteAbility; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.PermanentReferenceInCollectionPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.List; + +/** + * @author xenohedron + */ +public class GainControlAllUntapGainHasteEffect extends OneShotEffect { + + private final FilterPermanent filter; + + /** + * Gain control of all [filter] until end of turn. Untap them. They gain haste until end of turn. + */ + public GainControlAllUntapGainHasteEffect(FilterPermanent filter) { + super(Outcome.GainControl); + this.filter = filter; + makeText("them"); + } + + protected GainControlAllUntapGainHasteEffect(final GainControlAllUntapGainHasteEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public GainControlAllUntapGainHasteEffect copy() { + return new GainControlAllUntapGainHasteEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List affectedObjects = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game); + if (affectedObjects.isEmpty()) { + return false; + } + FilterPermanent affectedFilter = new FilterPermanent(); + affectedFilter.add(new PermanentReferenceInCollectionPredicate(affectedObjects, game)); + new GainControlAllEffect(Duration.EndOfTurn, affectedFilter).apply(game, source); + game.getState().processAction(game); + new UntapAllEffect(affectedFilter).apply(game, source); + game.addEffect(new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.EndOfTurn, affectedFilter), source); + return true; + } + + private void makeText(String those) { + this.staticText = "gain control of all " + filter.getMessage() + " until end of turn. Untap " + + those + ". They gain haste until end of turn"; + } + + public GainControlAllUntapGainHasteEffect withTextOptions(String those) { + makeText(those); + return this; + } + +}