mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
Bargain ability - fixed that cards can't be cast without full mana (#11089)
* [WOE] Fix Hamlet Glutton & friends * add tests
This commit is contained in:
parent
4b8e6ba9bc
commit
24315460fe
5 changed files with 130 additions and 6 deletions
|
|
@ -5,6 +5,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.BargainedCondition;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.keyword.BargainAbility;
|
||||
|
|
@ -57,9 +58,12 @@ public final class HamletGlutton extends CardImpl {
|
|||
enum HamletGluttonAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mage.cards.i;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.BargainedCondition;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.effects.common.CounterTargetEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.keyword.BargainAbility;
|
||||
|
|
@ -48,9 +49,12 @@ public final class IceOut extends CardImpl {
|
|||
enum IceOutAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mage.cards.j;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.BargainedCondition;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
|
|
@ -50,9 +51,12 @@ public final class JohannsStopgap extends CardImpl {
|
|||
enum JohannsStopgapAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,25 @@ public class BargainTest extends CardTestPlayerBase {
|
|||
// 4/4 Artifact
|
||||
private static final String stoneGolem = "Stone Golem";
|
||||
|
||||
/**
|
||||
* Hamlet Glutton
|
||||
* {5}{G}{G}
|
||||
* Creature — Giant
|
||||
*
|
||||
* Bargain (You may sacrifice an artifact, enchantment, or token as you cast this spell.)
|
||||
*
|
||||
* This spell costs {2} less to cast if it’s bargained.
|
||||
*
|
||||
* Trample
|
||||
*
|
||||
* When Hamlet Glutton enters the battlefield, you gain 3 life.
|
||||
*
|
||||
* 6/6
|
||||
*/
|
||||
private static final String glutton = "Hamlet Glutton";
|
||||
|
||||
private static final String relic = "Darksteel Relic"; // {0} Artifact
|
||||
|
||||
@Test
|
||||
public void testBargainNotPaidOuphe() {
|
||||
setStrictChooseMode(true);
|
||||
|
|
@ -227,4 +246,93 @@ public class BargainTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerB, stoneGolem, 0);
|
||||
assertExileCount(playerB, stoneGolem, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBargainOn5ManaGlutton() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
addCard(Zone.HAND, playerA, relic);
|
||||
|
||||
checkPlayableAbility("before relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", false);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic, true);
|
||||
|
||||
checkPlayableAbility("after relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, glutton, true);
|
||||
setChoice(playerA, true); // Do bargain.
|
||||
setChoice(playerA, relic); // Bargain the relic away.
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 + 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBargainOn7ManaGlutton() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
addCard(Zone.HAND, playerA, relic);
|
||||
|
||||
checkPlayableAbility("before relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic, true);
|
||||
|
||||
checkPlayableAbility("after relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, glutton, true);
|
||||
setChoice(playerA, true); // Do bargain.
|
||||
setChoice(playerA, relic); // Bargain the relic away.
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 + 3);
|
||||
assertTappedCount("Forest", true, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoBargainOn7ManaGlutton() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
addCard(Zone.HAND, playerA, relic);
|
||||
|
||||
checkPlayableAbility("before relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic, true);
|
||||
|
||||
checkPlayableAbility("after relic", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, glutton, true);
|
||||
setChoice(playerA, false); // No bargain.
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 + 3);
|
||||
assertTappedCount("Forest", true, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantBargainOn7ManaGlutton() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, glutton, true);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 + 3);
|
||||
assertTappedCount("Forest", true, 7);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,15 @@ public class BargainAbility extends StaticAbility implements OptionalAdditionalS
|
|||
));
|
||||
}
|
||||
|
||||
public static OptionalAdditionalCost makeBargainCost(){
|
||||
OptionalAdditionalCost cost = new OptionalAdditionalCostImpl(keywordText, reminderText, new SacrificeTargetCost(bargainFilter));
|
||||
cost.setRepeatable(false);
|
||||
return cost;
|
||||
}
|
||||
|
||||
public BargainAbility() {
|
||||
super(Zone.STACK, null);
|
||||
this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new SacrificeTargetCost(bargainFilter));
|
||||
this.additionalCost.setRepeatable(false);
|
||||
this.additionalCost = makeBargainCost();
|
||||
this.rule = additionalCost.getName() + ' ' + additionalCost.getReminderText();
|
||||
this.setRuleAtTheTop(true);
|
||||
this.addHint(BargainCostWasPaidHint.instance);
|
||||
|
|
@ -111,7 +116,6 @@ public class BargainAbility extends StaticAbility implements OptionalAdditionalS
|
|||
return activationKey != null && getActivationKey(source, game).equalsIgnoreCase(activationKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: remove with Tag Cost Tracking.
|
||||
* Return activation zcc key for searching spell's settings in source object
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue