From 07915394c71e047cc682236ca9f5add9c9ccef10 Mon Sep 17 00:00:00 2001 From: jimga150 Date: Sat, 4 May 2024 23:25:35 -0400 Subject: [PATCH] [REX] Implement Indominus Rex, Alpha (#12119) * Implement Indominus Rex, Alpha * Add draw ability * Add test * Add draw verification * fix errant comment * null check * switch to EntersBattlefieldAbility * Fix test, dont have to pick triggers now * use AsEntersBattlefieldAbility * move tests and rename * use appliedEffects in addCounter call * change AI hint * use game in getAbilities call * make ability text static, remove counter check * add comments on ability cards and add test case with subset of checked abilities * Update order of operations--discard, then add counters * add more tests (Nullhide Ferox, Madness) * check cards after move to graveyard * test for graveyard movement * check for hexproof base class and add test * refactor Indominus to make ability counters for each ability it comes across that is an instance of one of the checked abilites (counting HexproofBaseAbility) * remove commented code --- .../src/mage/cards/i/IndominusRexAlpha.java | 164 +++++++++++ .../mage/sets/JurassicWorldCollection.java | 1 + .../single/rex/IndominusRexAlphaTests.java | 264 ++++++++++++++++++ .../base/impl/CardTestPlayerAPIImpl.java | 25 +- .../java/mage/counters/AbilityCounter.java | 2 +- 5 files changed, 453 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/i/IndominusRexAlpha.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/rex/IndominusRexAlphaTests.java diff --git a/Mage.Sets/src/mage/cards/i/IndominusRexAlpha.java b/Mage.Sets/src/mage/cards/i/IndominusRexAlpha.java new file mode 100644 index 00000000000..2b2a0642505 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IndominusRexAlpha.java @@ -0,0 +1,164 @@ +package mage.cards.i; + +import java.util.*; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.*; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.counters.AbilityCounter; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetDiscard; + +/** + * + * @author jimga150 + */ +public final class IndominusRexAlpha extends CardImpl { + + private static final DynamicValue xValue = new CountersSourceCount(null); + + public IndominusRexAlpha(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U/B}{U/B}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.MUTANT); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // As Indominus Rex, Alpha enters the battlefield, discard any number of creature cards. It enters with a + // flying counter on it if a card discarded this way has flying. The same is true for first strike, + // double strike, deathtouch, hexproof, haste, indestructible, lifelink, menace, reach, trample, and vigilance. + this.addAbility(new AsEntersBattlefieldAbility(new IndominusRexAlphaCountersEffect())); + + // When Indominus Rex enters the battlefield, draw a card for each counter on it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(xValue))); + } + + private IndominusRexAlpha(final IndominusRexAlpha card) { + super(card); + } + + @Override + public IndominusRexAlpha copy() { + return new IndominusRexAlpha(this); + } +} + +// Based on MindMaggotsEffect +class IndominusRexAlphaCountersEffect extends OneShotEffect { + + private static final List copyableAbilities = Arrays.asList( + FlyingAbility.getInstance(), + FirstStrikeAbility.getInstance(), + DoubleStrikeAbility.getInstance(), + DeathtouchAbility.getInstance(), + HexproofAbility.getInstance(), // Hexproof has a number of variants that will be handled separately + HasteAbility.getInstance(), + IndestructibleAbility.getInstance(), + LifelinkAbility.getInstance(), + new MenaceAbility(), + ReachAbility.getInstance(), + TrampleAbility.getInstance(), + VigilanceAbility.getInstance() + ); + + IndominusRexAlphaCountersEffect() { + // AI will discard whole hand if this is set to a beneficial outcome without custom logic, which is bad + // practice. so we will just ask it to not discard anything + super(Outcome.AIDontUseIt); + + this.staticText = "discard any number of creature cards. It enters with a flying counter on it if a card " + + "discarded this way has flying. The same is true for first strike, double strike, deathtouch, " + + "hexproof, haste, indestructible, lifelink, menace, reach, trample, and vigilance."; + } + + private IndominusRexAlphaCountersEffect(final IndominusRexAlphaCountersEffect effect) { + super(effect); + } + + @Override + public IndominusRexAlphaCountersEffect copy() { + return new IndominusRexAlphaCountersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + + // EntersBattlefieldAbility is static, see AddCountersSourceEffect + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent == null) { + return true; + } + + TargetCard target = new TargetDiscard(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_CREATURE, controller.getId()); + controller.choose(outcome, controller.getHand(), target, source, game); + List chosenTargets = target.getTargets(); + + // Must discard before checking abilities and adding counters + // from MTG judge chat at https://chat.magicjudges.org/mtgrules/ + // + // jimga150: If Yixlid Jailer is on the battlefield, will discarding cards with Indominus cause indominus to + // get no counters from its ability? + // + // R0b_: The discarded card won't have any abilities in the graveyard and Indominus won't get a counter from it + controller.discard(new CardsImpl(target.getTargets()), false, source, game); + + //allow cards to move to graveyard before checking for abilities + game.getState().processAction(game); + + // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + List appliedEffects = (ArrayList) this.getValue("appliedEffects"); + + ArrayList abilitiesToAdd = new ArrayList<>(); + + for (Ability abilityToCopy : copyableAbilities) { + + for (UUID targetId : chosenTargets) { + + Card card = game.getCard(targetId); + if (card == null){ + continue; + } + + for (Ability ability : card.getAbilities(game)) { + if (abilitiesToAdd.stream().anyMatch(a -> a.getClass().isInstance(ability))){ + continue; + } + if (abilityToCopy.getClass().isInstance(ability)){ + abilitiesToAdd.add(ability); + } else if (ability instanceof HexproofBaseAbility) { + // Any subclass of HexproofBaseAbility gets added too--not just instances of HexproofAbility + abilitiesToAdd.add(ability); + } + } + + } + + } + + for (Ability abilityToCopy : abilitiesToAdd) { + permanent.addCounters(new AbilityCounter(abilityToCopy, 1), source.getControllerId(), source, game, appliedEffects); + } + return !abilitiesToAdd.isEmpty(); + } +} diff --git a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java index fc1c5d87594..1edafc96c6b 100644 --- a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java +++ b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java @@ -34,6 +34,7 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Henry Wu, InGen Geneticist", 12, Rarity.RARE, mage.cards.h.HenryWuInGenGeneticist.class)); cards.add(new SetCardInfo("Hunting Velociraptor", 4, Rarity.RARE, mage.cards.h.HuntingVelociraptor.class)); cards.add(new SetCardInfo("Ian Malcolm, Chaotician", 13, Rarity.RARE, mage.cards.i.IanMalcolmChaotician.class)); + cards.add(new SetCardInfo("Indominus Rex, Alpha", 14, Rarity.RARE, mage.cards.i.IndominusRexAlpha.class)); cards.add(new SetCardInfo("Indoraptor, the Perfect Hybrid", 15, Rarity.RARE, mage.cards.i.IndoraptorThePerfectHybrid.class)); cards.add(new SetCardInfo("Island", 22, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", "22b", Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/rex/IndominusRexAlphaTests.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/rex/IndominusRexAlphaTests.java new file mode 100644 index 00000000000..45c3bb387e1 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/rex/IndominusRexAlphaTests.java @@ -0,0 +1,264 @@ +package org.mage.test.cards.single.rex; + +import mage.abilities.keyword.HexproofFromPlaneswalkersAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author jimga150 + */ +public class IndominusRexAlphaTests extends CardTestPlayerBase { + + @Test + public void testIndominusRexAlphaAllAbilties() { + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + addCard(Zone.HAND, playerA, "Ornithopter", 1); // Flying + addCard(Zone.HAND, playerA, "Rograkh, Son of Rohgahh", 1); // First strike, menace, trample, Partner + addCard(Zone.HAND, playerA, "Adorned Pouncer", 1); // Double strike, Eternalize + addCard(Zone.HAND, playerA, "Ankle Biter", 1); // Deathtouch + addCard(Zone.HAND, playerA, "Gladecover Scout", 1); // Hexproof + addCard(Zone.HAND, playerA, "Banehound", 1); // Lifelink, haste + addCard(Zone.HAND, playerA, "Bontu the Glorified", 1); // Menace, indestructible + addCard(Zone.HAND, playerA, "Aerial Responder", 1); // Flying, vigilance, lifelink + addCard(Zone.HAND, playerA, "Stonecoil Serpent", 1); // Reach, trample, protection from multicolored + addCard(Zone.HAND, playerA, "Codespell Cleric", 1); // Vigilance + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Ornithopter^Rograkh, Son of Rohgahh^Adorned Pouncer^Ankle Biter^Gladecover Scout" + + "^Banehound^Bontu the Glorified^Aerial Responder^Stonecoil Serpent^Codespell Cleric"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FLYING, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FIRST_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DOUBLE_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DEATHTOUCH, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HEXPROOF, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HASTE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.INDESTRUCTIBLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.LIFELINK, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.MENACE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.REACH, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.TRAMPLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.VIGILANCE, 1); + + assertHandCount(playerA, 12); + + } + + @Test + public void testIndominusRexAlphaHexproofFromX() { + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + addCard(Zone.HAND, playerA, "Eradicator Valkyrie", 1); // Flying, lifelink, hexproof from planeswalker + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Eradicator Valkyrie"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FLYING, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HEXPROOF, 0); + assertCounterCount(playerA, "Indominus Rex, Alpha", HexproofFromPlaneswalkersAbility.getInstance().getRule(), 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.LIFELINK, 1); + + assertHandCount(playerA, 3); + + } + + @Test + public void testIndominusRexAlphaGraveyardMovement() { + + // When Rest in Peace enters the battlefield, exile all graveyards. + // If a card or token would be put into a graveyard from anywhere, exile it instead. + addCard(Zone.BATTLEFIELD, playerA, "Rest in Peace", 1); + + // This test verifies that indominus can check cards that have moved to zones other than the graveyard after + // they've been discarded with her ability. + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + addCard(Zone.HAND, playerA, "Ornithopter", 1); // Flying + addCard(Zone.HAND, playerA, "Rograkh, Son of Rohgahh", 1); // First strike, menace, trample, Partner + addCard(Zone.HAND, playerA, "Adorned Pouncer", 1); // Double strike, Eternalize + addCard(Zone.HAND, playerA, "Ankle Biter", 1); // Deathtouch + addCard(Zone.HAND, playerA, "Gladecover Scout", 1); // Hexproof + addCard(Zone.HAND, playerA, "Banehound", 1); // Lifelink, haste + addCard(Zone.HAND, playerA, "Bontu the Glorified", 1); // Menace, indestructible + addCard(Zone.HAND, playerA, "Aerial Responder", 1); // Flying, vigilance, lifelink + addCard(Zone.HAND, playerA, "Stonecoil Serpent", 1); // Reach, trample, protection from multicolored + addCard(Zone.HAND, playerA, "Codespell Cleric", 1); // Vigilance + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Ornithopter^Rograkh, Son of Rohgahh^Adorned Pouncer^Ankle Biter^Gladecover Scout" + + "^Banehound^Bontu the Glorified^Aerial Responder^Stonecoil Serpent^Codespell Cleric"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FLYING, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FIRST_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DOUBLE_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DEATHTOUCH, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HEXPROOF, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HASTE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.INDESTRUCTIBLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.LIFELINK, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.MENACE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.REACH, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.TRAMPLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.VIGILANCE, 1); + + assertHandCount(playerA, 12); + + } + + @Test + public void testIndominusRexAlphaSubset() { + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + addCard(Zone.HAND, playerA, "Ornithopter", 1); // Flying + addCard(Zone.HAND, playerA, "Rograkh, Son of Rohgahh", 1); // First strike, menace, trample, Partner + addCard(Zone.HAND, playerA, "Adorned Pouncer", 1); // Double strike, Eternalize + addCard(Zone.HAND, playerA, "Ankle Biter", 1); // Deathtouch + addCard(Zone.HAND, playerA, "Banehound", 1); // Lifelink, haste + addCard(Zone.HAND, playerA, "Bontu the Glorified", 1); // Menace, indestructible + addCard(Zone.HAND, playerA, "Aerial Responder", 1); // Flying, vigilance, lifelink + addCard(Zone.HAND, playerA, "Codespell Cleric", 1); // Vigilance + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Ornithopter^Rograkh, Son of Rohgahh^Adorned Pouncer^Ankle Biter" + + "^Banehound^Bontu the Glorified^Aerial Responder^Codespell Cleric"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FLYING, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FIRST_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DOUBLE_STRIKE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.DEATHTOUCH, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HASTE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.INDESTRUCTIBLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.LIFELINK, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.MENACE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.TRAMPLE, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.VIGILANCE, 1); + + assertHandCount(playerA, 10); + + } + + @Test + public void testIndominusRexAlphaDiscardReplacement() { + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + + // If a spell or ability an opponent controls causes you to discard Nullhide Ferox, + // put it onto the battlefield instead of putting it into your graveyard. + addCard(Zone.HAND, playerA, "Nullhide Ferox"); // Hexproof + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Nullhide Ferox"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HEXPROOF, 1); + + // Since the ability causing the discard was also owned by player A, Nullhide Ferox should not trigger, + // and it will be in the graveyard. + assertPermanentCount(playerA, "Nullhide Ferox", 0); + assertGraveyardCount(playerA, "Nullhide Ferox", 1); + + assertHandCount(playerA, 1); + + } + + @Test + public void testIndominusRexAlphaMadness() { + + addCard(Zone.HAND, playerA, "Indominus Rex, Alpha", 1); + + // Flying, haste + // Madness {B} (If you discard this card, discard it into exile. When you do, cast it for its madness cost + // or put it into your graveyard.) + addCard(Zone.HAND, playerA, "Kitchen Imp"); + + addCard(Zone.LIBRARY, playerA, "Swamp", 20); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Indominus Rex, Alpha", true); + + // Cards to discard + setChoice(playerA, "Kitchen Imp"); + + // Pick madness cast to happen first + setChoice(playerA, "When this card"); + + // Cast for madness + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.FLYING, 1); + assertCounterCount(playerA, "Indominus Rex, Alpha", CounterType.HASTE, 1); + + // Check that madness resulted in cast + assertPermanentCount(playerA, "Kitchen Imp", 1); + assertGraveyardCount(playerA, "Kitchen Imp", 0); + + assertHandCount(playerA, 2); + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index aaa52a86cb2..f3621d5048e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -1071,7 +1071,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement /** * Assert counter count on a permanent * - * @param cardName Name of the cards that should be counted. + * @param cardName Name of the card that should be counted. * @param type Type of the counter that should be counted. * @param count Expected count. */ @@ -1079,7 +1079,28 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement this.assertCounterCount(null, cardName, type, count); } + /** + * Assert counter count on a permanent + * + * @param player Player who owns the card named cardName + * @param cardName Name of the card that should be counted. + * @param type Type of the counter that should be counted. + * @param count Expected count. + */ public void assertCounterCount(Player player, String cardName, CounterType type, int count) throws AssertionError { + this.assertCounterCount(player, cardName, type.getName(), count); + } + + /** + * Assert counter count on a permanent + * + * @param player Player who owns the card named cardName + * @param cardName Name of the card that should be counted. + * @param counterName Name of the counter that should be counted. + * (for custom ability counters, use getRule() from the ability) + * @param count Expected count. + */ + public void assertCounterCount(Player player, String cardName, String counterName, int count) throws AssertionError { //Assert.assertNotEquals("", cardName); Permanent found = null; for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) { @@ -1089,7 +1110,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } } Assert.assertNotNull("There is no such permanent " + (player == null ? "" : "for player " + player.getName()) + " on the battlefield, cardName=" + cardName, found); - Assert.assertEquals("(Battlefield) Counter counts are not equal (" + cardName + ':' + type + ')', count, found.getCounters(currentGame).getCount(type)); + Assert.assertEquals("(Battlefield) Counter counts are not equal (" + cardName + ':' + counterName + ')', count, found.getCounters(currentGame).getCount(counterName)); } /** diff --git a/Mage/src/main/java/mage/counters/AbilityCounter.java b/Mage/src/main/java/mage/counters/AbilityCounter.java index d63463226b7..e2517997157 100644 --- a/Mage/src/main/java/mage/counters/AbilityCounter.java +++ b/Mage/src/main/java/mage/counters/AbilityCounter.java @@ -9,7 +9,7 @@ public class AbilityCounter extends Counter { private final Ability ability; - AbilityCounter(Ability ability, int count) { + public AbilityCounter(Ability ability, int count) { super(makeName(ability.getRule()), count); this.ability = ability; }