* Fixed available mana generation of Jungle Patrol (was no mana ability) and Priest of Yawgmoth (#6698).

This commit is contained in:
LevelX2 2020-07-31 13:53:07 +02:00
parent 2fb8f627c2
commit c343767e8e
5 changed files with 149 additions and 34 deletions

View file

@ -12,6 +12,7 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -43,13 +44,13 @@ public final class JunglePatrol extends CardImpl {
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// {1}{G}, {tap}: Create a 0/1 green Wall creature token with defender named Wood. // {1}{G}, {T}: Create a 0/1 green Wall creature token with defender named Wood.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WoodToken()), new ManaCostsImpl("{1}{G}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WoodToken()), new ManaCostsImpl("{1}{G}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
this.addAbility(ability); this.addAbility(ability);
// Sacrifice a token named Wood: Add {R}. // Sacrifice a token named Wood: Add {R}.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD,
new BasicManaEffect(Mana.RedMana(1), new PermanentsOnBattlefieldCount(filter)), new BasicManaEffect(Mana.RedMana(1), new PermanentsOnBattlefieldCount(filter)),
new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true)))); new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))));
} }

View file

@ -6,12 +6,15 @@ import mage.MageInt;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.common.HighestCMCOfPermanentValue;
import mage.abilities.dynamicvalue.common.SacrificeCostConvertedMana; import mage.abilities.dynamicvalue.common.SacrificeCostConvertedMana;
import mage.abilities.mana.DynamicManaAbility; import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.common.FilterControlledArtifactPermanent;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
@ -28,10 +31,14 @@ public final class PriestOfYawgmoth extends CardImpl {
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// {T}, Sacrifice an artifact: Add an amount of {B} equal to the sacrificed artifact's converted mana cost. // {T}, Sacrifice an artifact: Add an amount of {B} equal to the sacrificed artifact's converted mana cost.
Ability ability = new DynamicManaAbility(Mana.BlackMana(1), new SacrificeCostConvertedMana("artifact"), Ability ability = new DynamicManaAbility(Mana.BlackMana(1), new SacrificeCostConvertedMana("artifact"),
"add an amount of {B} equal to the sacrificed artifact's converted mana cost"); new TapSourceCost(),
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent()))); "add an amount of {B} equal to the sacrificed artifact's converted mana cost",
false,
new HighestCMCOfPermanentValue(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT, true)
);
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)));
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -13,15 +13,14 @@ import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
* *
* @author LevelX2 * @author LevelX2
*/ */
public class NonTappingManaAbilitiesTest extends CardTestPlayerBase { public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
@Test @Test
public void druidsRepositoryTest() { public void druidsRepositoryTest() {
setStrictChooseMode(true); setStrictChooseMode(true);
addCard(Zone.HAND, playerA, "Alaborn Grenadier", 1); //Creature {W}{W} addCard(Zone.HAND, playerA, "Alaborn Grenadier", 1); //Creature {W}{W}
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 2); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 2);
// Whenever a creature you control attacks, put a charge counter on Druids' Repository. // Whenever a creature you control attacks, put a charge counter on Druids' Repository.
// Remove a charge counter from Druids' Repository: Add one mana of any color. // Remove a charge counter from Druids' Repository: Add one mana of any color.
@ -30,36 +29,36 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
attack(1, playerA, "Silvercoat Lion"); attack(1, playerA, "Silvercoat Lion");
attack(1, playerA, "Silvercoat Lion"); attack(1, playerA, "Silvercoat Lion");
setChoice(playerA, "Whenever a creature you control"); setChoice(playerA, "Whenever a creature you control");
setStopAt(1, PhaseStep.END_COMBAT); setStopAt(1, PhaseStep.END_COMBAT);
execute(); execute();
assertTappedCount("Silvercoat Lion", true, 2); assertTappedCount("Silvercoat Lion", true, 2);
assertCounterCount(playerA,"Druids' Repository", CounterType.CHARGE, 2); assertCounterCount(playerA, "Druids' Repository", CounterType.CHARGE, 2);
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{Any}{Any}", manaOptions); assertManaOptions("{Any}{Any}", manaOptions);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Alaborn Grenadier"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Alaborn Grenadier");
setChoice(playerA, "White"); setChoice(playerA, "White");
setChoice(playerA, "White"); setChoice(playerA, "White");
setStopAt(1, PhaseStep.END_TURN); setStopAt(1, PhaseStep.END_TURN);
execute(); execute();
assertCounterCount(playerA,"Druids' Repository", CounterType.CHARGE, 0); assertCounterCount(playerA, "Druids' Repository", CounterType.CHARGE, 0);
assertPermanentCount(playerA, "Alaborn Grenadier", 1); assertPermanentCount(playerA, "Alaborn Grenadier", 1);
} }
@Test @Test
public void TestWorkhorse() { public void TestWorkhorse() {
setStrictChooseMode(true); setStrictChooseMode(true);
// Workhorse enters the battlefield with four +1/+1 counters on it. // Workhorse enters the battlefield with four +1/+1 counters on it.
// Remove a +1/+1 counter from Workhorse: Add {C}. // Remove a +1/+1 counter from Workhorse: Add {C}.
addCard(Zone.BATTLEFIELD, playerA, "Workhorse", 1); addCard(Zone.BATTLEFIELD, playerA, "Workhorse", 1);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN); setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute(); execute();
@ -68,7 +67,7 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{C}{C}{C}{C}", manaOptions); assertManaOptions("{C}{C}{C}{C}", manaOptions);
} }
@Test @Test
public void TestMorselhoarder() { public void TestMorselhoarder() {
@ -108,7 +107,7 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
assertManaOptions("{W}{B}{B}{B}", manaOptions); assertManaOptions("{W}{B}{B}{B}", manaOptions);
assertManaOptions("{B}{B}{B}{B}", manaOptions); assertManaOptions("{B}{B}{B}{B}", manaOptions);
} }
@Test @Test
public void TestCrystallineCrawler() { public void TestCrystallineCrawler() {
setStrictChooseMode(true); setStrictChooseMode(true);
@ -128,19 +127,17 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
assertManaOptions("{Any}{Any}", manaOptions); assertManaOptions("{Any}{Any}", manaOptions);
} }
@Test @Test
public void TestCoalGolemAndDromarsAttendant() { public void TestCoalGolemAndDromarsAttendant() {
setStrictChooseMode(true); setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// {1}, Sacrifice Dromar's Attendant: Add {W}{U}{B}. // {1}, Sacrifice Dromar's Attendant: Add {W}{U}{B}.
addCard(Zone.BATTLEFIELD, playerA, "Dromar's Attendant", 1); addCard(Zone.BATTLEFIELD, playerA, "Dromar's Attendant", 1);
// {3}, Sacrifice Coal Golem: Add {R}{R}{R}. // {3}, Sacrifice Coal Golem: Add {R}{R}{R}.
addCard(Zone.BATTLEFIELD, playerA, "Coal Golem", 1); addCard(Zone.BATTLEFIELD, playerA, "Coal Golem", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -152,23 +149,23 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
assertManaOptions("{W}{U}{B}", manaOptions); assertManaOptions("{W}{U}{B}", manaOptions);
assertManaOptions("{R}{R}{R}", manaOptions); assertManaOptions("{R}{R}{R}", manaOptions);
} }
/** /**
* The order the mana abilities are checked during available mana calculation does matter. * The order the mana abilities are checked during available mana
* Because Coal Golem can not be used as long as Dromar's Attendant is not used yet to produce the 3 mana. * calculation does matter. Because Coal Golem can not be used as long as
* Dromar's Attendant is not used yet to produce the 3 mana.
*/ */
@Test @Test
public void TestCoalGolemAndDromarsAttendantOrder2() { public void TestCoalGolemAndDromarsAttendantOrder2() {
setStrictChooseMode(true); setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// {3}, Sacrifice Coal Golem: Add {R}{R}{R}. // {3}, Sacrifice Coal Golem: Add {R}{R}{R}.
addCard(Zone.BATTLEFIELD, playerA, "Coal Golem", 1); addCard(Zone.BATTLEFIELD, playerA, "Coal Golem", 1);
// {1}, Sacrifice Dromar's Attendant: Add {W}{U}{B}. // {1}, Sacrifice Dromar's Attendant: Add {W}{U}{B}.
addCard(Zone.BATTLEFIELD, playerA, "Dromar's Attendant", 1); addCard(Zone.BATTLEFIELD, playerA, "Dromar's Attendant", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -180,5 +177,28 @@ public class NonTappingManaAbilitiesTest extends CardTestPlayerBase {
assertManaOptions("{W}{U}{B}", manaOptions); assertManaOptions("{W}{U}{B}", manaOptions);
assertManaOptions("{R}{R}{R}", manaOptions); assertManaOptions("{R}{R}{R}", manaOptions);
} }
@Test
public void TestJunglePatrol() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
// {1}{G}, {T}: Create a 0/1 green Wall creature token with defender named Wood.
// Sacrifice a token named Wood: Add {R}.
addCard(Zone.BATTLEFIELD, playerA, "Jungle Patrol", 1);
} activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G}, {T}: Create");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G}, {T}: Create");
activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G}, {T}: Create");
setStopAt(5, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Wood", 3);
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{R}{R}{R}", manaOptions);
}
}

View file

@ -289,5 +289,25 @@ public class TappedForManaRelatedTest extends CardTestPlayerBase {
assertManaOptions("{G}{G}{G}{G}{G}{G}{G}", manaOptions); assertManaOptions("{G}{G}{G}{G}{G}{G}{G}", manaOptions);
} }
@Test
public void TestPriestOfYawgmoth() {
setStrictChooseMode(true);
// {T}, Sacrifice an artifact: Add an amount of {B} equal to the sacrificed artifact's converted mana cost.
addCard(Zone.BATTLEFIELD, playerA, "Priest of Yawgmoth", 1); // Creature {1}{B} 1/2
addCard(Zone.BATTLEFIELD, playerA, "Abandoned Sarcophagus", 1); // {3}
addCard(Zone.BATTLEFIELD, playerA, "Accorder's Shield", 1); // {0}
addCard(Zone.BATTLEFIELD, playerA, "Adarkar Sentinel", 1); // {5}
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertAllCommandsUsed();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{B}{B}{B}{B}{B}", manaOptions);
}
} }

View file

@ -0,0 +1,67 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author LevelX2
*/
public class HighestCMCOfPermanentValue implements DynamicValue {
private final FilterPermanent filter;
private final boolean onlyIfCanBeSacrificed;
public HighestCMCOfPermanentValue(FilterPermanent filter, boolean onlyIfCanBeSacrificed) {
super();
this.filter = filter;
this.onlyIfCanBeSacrificed = onlyIfCanBeSacrificed;
}
public HighestCMCOfPermanentValue(final HighestCMCOfPermanentValue dynamicValue) {
this.filter = dynamicValue.filter;
this.onlyIfCanBeSacrificed = dynamicValue.onlyIfCanBeSacrificed;
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int value = 0;
Player controller = game.getPlayer(sourceAbility.getControllerId());
if (controller != null) {
for (Permanent permanent : game.getBattlefield()
.getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility.getSourceId(), game)) {
if ((!onlyIfCanBeSacrificed || controller.canPaySacrificeCost(permanent, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game))
&& permanent.getConvertedManaCost() > value) {
value = permanent.getConvertedManaCost();
}
}
}
return value;
}
@Override
public HighestCMCOfPermanentValue copy() {
return new HighestCMCOfPermanentValue(this);
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return filter.getMessage();
}
}