diff --git a/Mage.Sets/src/mage/sets/coldsnap/ThrummingStone.java b/Mage.Sets/src/mage/sets/coldsnap/ThrummingStone.java index 2678180435..c7f1a281d0 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/ThrummingStone.java +++ b/Mage.Sets/src/mage/sets/coldsnap/ThrummingStone.java @@ -28,11 +28,19 @@ package mage.sets.coldsnap; import java.util.UUID; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.keyword.RippleEffect; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.keyword.RippleAbility; import mage.cards.CardImpl; import mage.constants.*; import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; /** * @@ -41,14 +49,15 @@ import mage.filter.FilterSpell; public class ThrummingStone extends CardImpl { //applies to all spells - private static final FilterSpell anySpellFilter = new FilterSpell(); + private static final FilterSpell anySpellFilter = new FilterSpell("Spells you cast"); public ThrummingStone(UUID ownerId) { super(ownerId, 142, "Thrumming Stone", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{5}"); this.expansionSetCode = "CSP"; this.supertype.add("Legendary"); - addAbility(new SpellCastControllerTriggeredAbility(new RippleEffect(4, false), anySpellFilter, false, true)); + // spells you cast have Ripple 4 + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ThrummingStoneGainAbilitySpellsEffect(new RippleAbility(4), anySpellFilter))); } public ThrummingStone(final ThrummingStone card) { @@ -62,3 +71,50 @@ public class ThrummingStone extends CardImpl { } +class ThrummingStoneGainAbilitySpellsEffect extends ContinuousEffectImpl { + + private final Ability ability; + private final FilterSpell filter; + + + public ThrummingStoneGainAbilitySpellsEffect(Ability ability, FilterSpell filter) { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + this.ability = ability; + this.filter = filter; + staticText = filter.getMessage() + " have " + ability.getRule(); + } + + public ThrummingStoneGainAbilitySpellsEffect(final ThrummingStoneGainAbilitySpellsEffect effect) { + super(effect); + this.ability = effect.ability; + this.filter = effect.filter; + } + + @Override + public ThrummingStoneGainAbilitySpellsEffect copy() { + return new ThrummingStoneGainAbilitySpellsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (player != null && permanent != null) { + for (StackObject stackObject : game.getStack()) { + // only spells cast, so no copies of spells + if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) { + Spell spell = (Spell) stackObject; + if (filter.match(spell, game)) { + if (!spell.getAbilities().contains(ability)) { + game.getState().addOtherAbility(spell.getCard(), ability); + } + } + } + } + return true; + } + return false; + } +} + + diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/ThrummingStoneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/ThrummingStoneTest.java new file mode 100644 index 0000000000..0776f50e70 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/ThrummingStoneTest.java @@ -0,0 +1,61 @@ +package org.mage.test.cards.abilities.other; + +import jdk.nashorn.internal.ir.annotations.Ignore; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author klayhamn + */ +public class ThrummingStoneTest extends CardTestPlayerBase { + + @Test + public void testApplyForNoneRippleCardsWhenSingleRipple() throws Exception { + + removeAllCardsFromLibrary(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Thrumming Stone"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Shadowborn Apostle"); + + addCard(Zone.LIBRARY, playerA, "Shadowborn Apostle", 1); + addCard(Zone.LIBRARY, playerA, "Swamp", 3); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shadowborn Apostle"); + setChoice(playerA, "Yes"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Shadowborn Apostle", 2); + + } + + @Test + @Ignore // FIXME: This still fails + public void testApplyForNoneRippleCardsWhenMultiRipple() throws Exception { + + removeAllCardsFromLibrary(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Thrumming Stone"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Shadowborn Apostle"); + + addCard(Zone.LIBRARY, playerA, "Shadowborn Apostle"); + addCard(Zone.LIBRARY, playerA, "Swamp", 3); + addCard(Zone.LIBRARY, playerA, "Shadowborn Apostle"); + + skipInitShuffling(); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shadowborn Apostle"); + setChoice(playerA, "Yes"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Shadowborn Apostle", 3); + + } +}