diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ConditionalCostModificationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ConditionalCostModificationTest.java new file mode 100644 index 00000000000..8dbe972ea37 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/ConditionalCostModificationTest.java @@ -0,0 +1,139 @@ +package org.mage.test.cards.continuous; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.condition.common.NotMyTurnCondition; +import mage.abilities.decorator.ConditionalCostModificationEffect; +import mage.abilities.effects.common.cost.AbilitiesCostReductionControllerEffect; +import mage.abilities.effects.common.cost.SpellsCostIncreasementAllEffect; +import mage.abilities.keyword.EquipAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class ConditionalCostModificationTest extends CardTestPlayerBase { + + // Dagger of the Worthy {2} + // Equipped creature gets +2/+0 and has afflict 1. + // Equip {2} + + @Test + public void test_NoModification() { + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Dagger of the Worthy", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTappedCount("Mountain", true, 2); + assertTappedCount("Mountain", false, 0); + } + + @Test + public void test_ModificationNormal() { + addCustomCardWithAbility("mod", playerA, new SimpleStaticAbility(new AbilitiesCostReductionControllerEffect(EquipAbility.class, "equip"))); + + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Dagger of the Worthy", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTappedCount("Mountain", true, 1); + assertTappedCount("Mountain", false, 1); + } + + @Test + public void test_ModificationConditionalActive() { + addCustomCardWithAbility("mod", playerA, new SimpleStaticAbility( + new ConditionalCostModificationEffect( + new AbilitiesCostReductionControllerEffect(EquipAbility.class, "equip"), + MyTurnCondition.instance, + "" + ) + )); + + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Dagger of the Worthy", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTappedCount("Mountain", true, 1); + assertTappedCount("Mountain", false, 1); + } + + @Test + public void test_ModificationConditionalNotActive() { + addCustomCardWithAbility("mod", playerA, new SimpleStaticAbility( + new ConditionalCostModificationEffect( + new AbilitiesCostReductionControllerEffect(EquipAbility.class, "equip"), + NotMyTurnCondition.instance, + "" + ) + )); + + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Dagger of the Worthy", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTappedCount("Mountain", true, 2); + assertTappedCount("Mountain", false, 0); + } + + @Test + public void test_ModificationConditionalNotActiveWithOtherEffect() { + addCustomCardWithAbility("mod", playerA, new SimpleStaticAbility( + new ConditionalCostModificationEffect( + new AbilitiesCostReductionControllerEffect(EquipAbility.class, "equip"), + NotMyTurnCondition.instance, + new SpellsCostIncreasementAllEffect(1), + "" + ) + )); + + addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); + addCard(Zone.BATTLEFIELD, playerA, "Dagger of the Worthy", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + addCard(Zone.HAND, playerA, "Lightning Bolt", 1); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears"); // no mod, 2 cost + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB); // +1 for spell, 2 cost + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertTappedCount("Mountain", true, 4); + assertTappedCount("Mountain", false, 0); + assertLife(playerB, 20 - 3); + } + +} diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalCostModificationEffect.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalCostModificationEffect.java new file mode 100644 index 00000000000..cecf01c6245 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalCostModificationEffect.java @@ -0,0 +1,86 @@ +package mage.abilities.decorator; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.effects.CostModificationEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.constants.Duration; +import mage.game.Game; + +/** + * @author JayDi85 + */ +public class ConditionalCostModificationEffect extends CostModificationEffectImpl { + + protected CostModificationEffect effect; + protected CostModificationEffect otherwiseEffect; + protected Condition condition; + protected boolean conditionState; + + public ConditionalCostModificationEffect(CostModificationEffect effect, Condition condition, String text) { + this(effect, condition, null, text); + } + + public ConditionalCostModificationEffect(CostModificationEffect effect, Condition condition, CostModificationEffect otherwiseEffect, + String text) { + super(effect.getDuration(), effect.getOutcome(), effect.getModificationType()); + this.effect = effect; + this.condition = condition; + this.otherwiseEffect = otherwiseEffect; + if (text != null) { + this.setText(text); + } + } + + public ConditionalCostModificationEffect(final ConditionalCostModificationEffect effect) { + super(effect); + this.effect = (CostModificationEffect) effect.effect.copy(); + if (effect.otherwiseEffect != null) { + this.otherwiseEffect = (CostModificationEffect) effect.otherwiseEffect.copy(); + } + this.condition = effect.condition; + this.conditionState = effect.conditionState; + } + + @Override + public boolean isDiscarded() { + return effect.isDiscarded() || (otherwiseEffect != null && otherwiseEffect.isDiscarded()); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + conditionState = condition.apply(game, source); + if (conditionState) { + effect.setTargetPointer(this.targetPointer); + return effect.apply(game, source, abilityToModify); + } else if (otherwiseEffect != null) { + otherwiseEffect.setTargetPointer(this.targetPointer); + return otherwiseEffect.apply(game, source, abilityToModify); + } + if (!conditionState && effect.getDuration() == Duration.OneUse) { + used = true; + } + if (!conditionState && effect.getDuration() == Duration.Custom) { + this.discard(); + } + return false; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + conditionState = condition.apply(game, source); + if (conditionState) { + effect.setTargetPointer(this.targetPointer); + return effect.applies(abilityToModify, source, game); + } else if (otherwiseEffect != null) { + otherwiseEffect.setTargetPointer(this.targetPointer); + return otherwiseEffect.applies(abilityToModify, source, game); + } + return false; + } + + @Override + public ConditionalCostModificationEffect copy() { + return new ConditionalCostModificationEffect(this); + } +}