diff --git a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java index 7377f176bcd..f34ddeec7b2 100644 --- a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java +++ b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java @@ -46,6 +46,7 @@ import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.game.stack.Spell; import mage.util.CardUtil; /** @@ -111,9 +112,15 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) { - Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.isCreature())) { - return true; + if (abilityToModify.getControllerId().equals(source.getControllerId())) { + Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); + if (spell != null) { + return spell.isCreature(); + } else { + // used at least for flashback ability because Flashback ability doesn't use stack or for getPlayables where spell is not cast yet + Card sourceCard = game.getCard(abilityToModify.getSourceId()); + return sourceCard != null && sourceCard.isCreature(); + } } } return false; diff --git a/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java b/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java index 627ebf68497..40dea7f8bf7 100644 --- a/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java +++ b/Mage.Sets/src/mage/cards/c/CentaurOmenreader.java @@ -35,6 +35,7 @@ import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; @@ -49,15 +50,16 @@ import mage.game.permanent.Permanent; public class CentaurOmenreader extends CardImpl { private static final FilterCard filter = new FilterCard("creature spells"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } public CentaurOmenreader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); addSuperType(SuperType.SNOW); - this.subtype.add("Centaur"); - this.subtype.add("Shaman"); + this.subtype.add(SubType.CENTAUR); + this.subtype.add(SubType.SHAMAN); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java index 52720812984..147de4902ad 100644 --- a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java +++ b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java @@ -45,6 +45,7 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.stack.Spell; import mage.util.CardUtil; /** @@ -54,9 +55,9 @@ import mage.util.CardUtil; public class RakdosLordOfRiots extends CardImpl { public RakdosLordOfRiots(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{R}{R}"); addSuperType(SuperType.LEGENDARY); - this.subtype.add("Demon"); + this.subtype.add(SubType.DEMON); this.power = new MageInt(6); this.toughness = new MageInt(6); @@ -102,12 +103,12 @@ class RakdosLordOfRiotsCantCastEffect extends ContinuousRuleModifyingEffectImpl public RakdosLordOfRiotsCantCastEffect copy() { return new RakdosLordOfRiotsCantCastEffect(this); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.CAST_SPELL; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getSourceId().equals(source.getSourceId())) { @@ -147,9 +148,15 @@ class RakdosLordOfRiotsCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) { - Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.isCreature())) { - return true; + if (abilityToModify.getControllerId().equals(source.getControllerId())) { + Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); + if (spell != null) { + return spell.isCreature(); + } else { + // used at least for flashback ability because Flashback ability doesn't use stack or for getPlayables where spell is not cast yet + Card sourceCard = game.getCard(abilityToModify.getSourceId()); + return sourceCard != null && sourceCard.isCreature(); + } } } return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java index 0cb57e84577..73ee7046d9b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/CostModificationTest.java @@ -2,6 +2,7 @@ package org.mage.test.cards.cost.modification; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -140,44 +141,80 @@ public class CostModificationTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Fated Conflagration", 1); assertGraveyardCount(playerB, "Carnivorous Moss-Beast", 1); } - + /* * Reported bug: Grand Arbiter Augustin IV makes moth spells you cast and your opponent cast {1} more. Should only affect opponent's spells costs. - */ + */ @Test public void testArbiterIncreasingCostBothPlayers() { - + String gArbiter = "Grand Arbiter Augustin IV"; String divination = "Divination"; String doomBlade = "Doom Blade"; - + /* - Grand Arbiter Augustin IV {2}{W}{U} + Grand Arbiter Augustin IV {2}{W}{U} 2/3 Legendary Creature - Human Advisor White spells you cast cost 1 less to cast. Blue spells you cast cost 1 less to cast. Spells your opponents cast cost 1 more to cast. - */ + */ addCard(Zone.BATTLEFIELD, playerA, gArbiter); addCard(Zone.HAND, playerA, divination); // {2}{U} Sorcery: draw two cards addCard(Zone.BATTLEFIELD, playerA, "Island", 2); - + addCard(Zone.HAND, playerB, doomBlade); addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); // {1}{B} Instant: destroy target non-black creature - + // Divination should only cost {1}{U} now with the cost reduction in place for your blue spells. castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, divination); - + // Doom Blade cast by the opponent should cost {2}{B} now with the cost increase in effect for opponent spells. castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, doomBlade, gArbiter); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - + assertGraveyardCount(playerA, divination, 1); assertHandCount(playerA, 2); assertTappedCount("Island", true, 2); assertPermanentCount(playerA, gArbiter, 1); assertHandCount(playerB, doomBlade, 1); } + + /** + * Zoetic Cavern's cast as creature cost is not modified as Animar, Soul of + * Elements gains counters. + */ + @Test + public void ReduceCostToCastZoeticCavern() { + + // Protection from white and from black + // Whenever you cast a creature spell, put a +1/+1 counter on Animar, Soul of Elements. + // Creature spells you cast cost {1} less to cast for each +1/+1 counter on Animar. + addCard(Zone.BATTLEFIELD, playerA, "Animar, Soul of Elements"); + + addCard(Zone.HAND, playerA, "Silvercoat Lion", 2); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + + addCard(Zone.HAND, playerA, "Zoetic Cavern"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + + playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Zoetic Cavern"); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Silvercoat Lion", 2); + assertCounterCount(playerA, "Animar, Soul of Elements", CounterType.P1P1, 3); + + assertHandCount(playerA, "Zoetic Cavern", 0); + assertPermanentCount(playerA, "Zoetic Cavern", 0); + + assertTappedCount("Plains", false, 2); // 2 for 1st Lion 1 for 2nd lion and only 1 mana needed to cast face down Zoetic + + } }