mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
* Fixed available mana generation of Jungle Patrol (was no mana ability) and Priest of Yawgmoth (#6698).
This commit is contained in:
parent
2fb8f627c2
commit
c343767e8e
5 changed files with 149 additions and 34 deletions
|
@ -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))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue