fix #11811 (Mob Rule) with new common class to handle logic

This commit is contained in:
xenohedron 2024-02-18 00:27:50 -05:00
parent 920d75377d
commit ead385a03b
6 changed files with 196 additions and 72 deletions

View file

@ -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,15 +60,7 @@ 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. " +

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 cant 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);
}
}

View file

@ -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<Permanent> 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;
}
}