implement [M3C] Barrowgoyf

This commit is contained in:
Susucre 2024-05-30 19:28:36 +02:00
parent fac1861c9f
commit 7543274659
4 changed files with 173 additions and 8 deletions

View file

@ -0,0 +1,60 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.MillThenPutInHandEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessPlusOneSourceEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author Plopman
*/
public final class Barrowgoyf extends CardImpl {
private static final DynamicValue powerValue = CardTypesInGraveyardCount.ALL;
public Barrowgoyf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.LHURGOYF);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// Barrowgoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue)));
// Whenever Barrowgoyf deals combat damage to a player, you may mill that many cards. If you do, you may put a creature card from among them into your hand.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new MillThenPutInHandEffect(SavedDamageValue.MANY, StaticFilters.FILTER_CARD_CREATURE)
.setText("you may mill that many cards. If you do, you may put a creature card from among them into your hand")
));
}
private Barrowgoyf(final Barrowgoyf card) {
super(card);
}
@Override
public Barrowgoyf copy() {
return new Barrowgoyf(this);
}
}

View file

@ -35,6 +35,7 @@ public final class ModernHorizons3Commander extends ExpansionSet {
cards.add(new SetCardInfo("Austere Command", 167, Rarity.RARE, mage.cards.a.AustereCommand.class));
cards.add(new SetCardInfo("Azlask, the Swelling Scourge", 5, Rarity.MYTHIC, mage.cards.a.AzlaskTheSwellingScourge.class));
cards.add(new SetCardInfo("Azorius Chancery", 319, Rarity.COMMON, mage.cards.a.AzoriusChancery.class));
cards.add(new SetCardInfo("Barrowgoyf", 50, Rarity.RARE, mage.cards.b.Barrowgoyf.class));
cards.add(new SetCardInfo("Battlefield Forge", 321, Rarity.RARE, mage.cards.b.BattlefieldForge.class));
cards.add(new SetCardInfo("Bident of Thassa", 177, Rarity.RARE, mage.cards.b.BidentOfThassa.class));
cards.add(new SetCardInfo("Bloodbraid Challenger", 70, Rarity.RARE, mage.cards.b.BloodbraidChallenger.class));

View file

@ -0,0 +1,88 @@
package org.mage.test.cards.single.m3c;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author Susucr
*/
public class BarrowgoyfTest extends CardTestPlayerBase {
/**
* {@link mage.cards.b.Barrowgoyf Barrowgoyf} {2}{B}
* Deathtouch, Lifelink
* Barrowgoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.
* Whenever Barrowgoyf deals combat damage to a player, you may mill that many cards. If you do, you may put a creature card from among them into your hand.
* * / 1+*
*/
private static final String barrowgoyf = "Barrowgoyf";
@Test
public void test_Simple() {
setStrictChooseMode(true);
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerA, barrowgoyf);
addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment
addCard(Zone.LIBRARY, playerA, "Baneslayer Angel");
addCard(Zone.LIBRARY, playerA, "Plains");
attack(1, playerA, barrowgoyf, playerB);
setChoice(playerA, "Baneslayer Angel"); // return this to hand.
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 20 - 2);
assertGraveyardCount(playerA, 1);
assertHandCount(playerA, "Baneslayer Angel", 1);
assertPowerToughness(playerA, barrowgoyf, 3, 4);
}
@Test
public void test_Simple_NoReturn() {
setStrictChooseMode(true);
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerA, barrowgoyf);
addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment
addCard(Zone.LIBRARY, playerA, "Baneslayer Angel");
addCard(Zone.LIBRARY, playerA, "Plains");
attack(1, playerA, barrowgoyf, playerB);
setChoice(playerA, TestPlayer.CHOICE_SKIP); // decide to not return.
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 20 - 2);
assertGraveyardCount(playerA, 2);
assertPowerToughness(playerA, barrowgoyf, 4, 5);
}
@Test
public void test_Simple_CantReturn() {
setStrictChooseMode(true);
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerA, barrowgoyf);
addCard(Zone.GRAVEYARD, playerB, "Bitterblossom"); // Tribal Enchantment
addCard(Zone.GRAVEYARD, playerB, "Grizzly Bears");
addCard(Zone.LIBRARY, playerA, "Brainstorm");
addCard(Zone.LIBRARY, playerA, "Plains");
addCard(Zone.LIBRARY, playerA, "Invasion of Zendikar");
attack(1, playerA, barrowgoyf, playerB);
setChoice(playerA, TestPlayer.CHOICE_SKIP); // decide to not return. There was no choice anyway.
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 20 - 3);
assertGraveyardCount(playerA, 3);
assertPowerToughness(playerA, barrowgoyf, 6, 7);
}
}

View file

@ -2,6 +2,8 @@ package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -24,7 +26,7 @@ import java.util.stream.Collectors;
*/
public class MillThenPutInHandEffect extends OneShotEffect {
private final int amount;
private final DynamicValue amount;
private final boolean optional;
private final int maxAmountReturned; // maximum number of cards returned. e.g. 2 for "up to two"
private final FilterCard filter;
@ -63,6 +65,22 @@ public class MillThenPutInHandEffect extends OneShotEffect {
}
public MillThenPutInHandEffect(int amount, FilterCard filter, Effect otherwiseEffect, boolean optional, int maxReturnedCard) {
this(StaticValue.get(amount), filter, otherwiseEffect, optional, maxReturnedCard);
}
public MillThenPutInHandEffect(DynamicValue amount, FilterCard filter) {
this(amount, filter, true);
}
public MillThenPutInHandEffect(DynamicValue amount, FilterCard filter, boolean optional) {
this(amount, filter, null, optional);
}
public MillThenPutInHandEffect(DynamicValue amount, FilterCard filter, Effect otherwiseEffect, boolean optional) {
this(amount, filter, otherwiseEffect, optional, 1);
}
public MillThenPutInHandEffect(DynamicValue amount, FilterCard filter, Effect otherwiseEffect, boolean optional, int maxReturnedCard) {
super(Outcome.Benefit);
this.amount = amount;
this.filter = filter;
@ -92,7 +110,8 @@ public class MillThenPutInHandEffect extends OneShotEffect {
if (player == null) {
return false;
}
Cards cards = player.millCards(amount, source, game);
int toMill = amount.calculate(game, source, this);
Cards cards = player.millCards(toMill, source, game);
if (cards.isEmpty()) {
return applyOtherwiseEffect(game, source);
}
@ -132,12 +151,9 @@ public class MillThenPutInHandEffect extends OneShotEffect {
return staticText;
}
StringBuilder sb = new StringBuilder("mill ");
if (amount == 1) {
sb.append("a card. ");
} else {
sb.append(CardUtil.numberToText(amount));
sb.append(" cards. ");
}
String value = amount.toString();
sb.append(CardUtil.numberToText(value, "a"));
sb.append(value.equals("1") ? " card" : " cards");
if (optional) {
sb.append("You may put ");
} else {