diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DruidsRepository.java b/Mage.Sets/src/mage/sets/avacynrestored/DruidsRepository.java index 1cde1684152..68cef558365 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/DruidsRepository.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/DruidsRepository.java @@ -29,7 +29,7 @@ package mage.sets.avacynrestored; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.effects.common.AddManaOfAnyColorEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; @@ -54,7 +54,7 @@ public class DruidsRepository extends CardImpl { this.color.setGreen(true); // Whenever a creature you control attacks, put a charge counter on Druids' Repository. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new AddCountersSourceEffect(CounterType.CHARGE.createInstance()))); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new AddCountersSourceEffect(CounterType.CHARGE.createInstance()))); // Remove a charge counter from Druids' Repository: Add one mana of any color to your mana pool. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/GleamOfBattle.java b/Mage.Sets/src/mage/sets/dragonsmaze/GleamOfBattle.java index 7b12e5da86b..7cb1c50cc33 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/GleamOfBattle.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/GleamOfBattle.java @@ -30,7 +30,7 @@ package mage.sets.dragonsmaze; import java.util.UUID; import mage.constants.CardType; import mage.constants.Rarity; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.counters.CounterType; @@ -49,7 +49,7 @@ public class GleamOfBattle extends CardImpl { this.color.setWhite(true); // Whenever a creature you control attacks, put a +1/+1 counter on it. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, true)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, true)); } public GleamOfBattle(final GleamOfBattle card) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/MarduAscendancy.java b/Mage.Sets/src/mage/sets/khansoftarkir/MarduAscendancy.java index 4827d767d75..edef1fa596b 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/MarduAscendancy.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/MarduAscendancy.java @@ -28,7 +28,7 @@ package mage.sets.khansoftarkir; import java.util.UUID; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.effects.common.CreateTokenEffect; @@ -69,7 +69,7 @@ public class MarduAscendancy extends CardImpl { this.color.setWhite(true); // Whenever a nontoken creature you control attacks, put a 1/1 red Goblin creature token onto the battlefield tapped and attacking. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new CreateTokenEffect(new GoblinToken(expansionSetCode), 1, true, true), false, attackFilter)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new CreateTokenEffect(new GoblinToken(expansionSetCode), 1, true, true), false, attackFilter)); // Sacrifice Mardu Ascendancy: Creatures you control get +0/+3 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(0, 3, Duration.EndOfTurn, filter, false), diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/TrailOfMystery.java b/Mage.Sets/src/mage/sets/khansoftarkir/TrailOfMystery.java index ef726b76df7..10b9d413d22 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/TrailOfMystery.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/TrailOfMystery.java @@ -41,8 +41,6 @@ import mage.constants.Zone; import mage.filter.common.FilterBasicLandCard; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.other.FaceDownPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; import mage.target.common.TargetCardInLibrary; /** @@ -98,6 +96,6 @@ class TrailOfMysteryTriggeredAbility extends TurnedFaceUpAllTriggeredAbility { @Override public String getRule() { - return "Whenever a permanent you control is turned face up, if it's a creature, it gets +2/+2 until end of turn"; + return "Whenever a permanent you control is turned face up, if it's a creature, it gets +2/+2 until end of turn."; } } diff --git a/Mage.Sets/src/mage/sets/magic2015/LeechingSliver.java b/Mage.Sets/src/mage/sets/magic2015/LeechingSliver.java index 779de36d925..3dfb904d959 100644 --- a/Mage.Sets/src/mage/sets/magic2015/LeechingSliver.java +++ b/Mage.Sets/src/mage/sets/magic2015/LeechingSliver.java @@ -28,7 +28,7 @@ package mage.sets.magic2015; import mage.MageInt; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.effects.common.LoseLifeDefendingPlayerEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -59,7 +59,7 @@ public class LeechingSliver extends CardImpl { this.toughness = new MageInt(1); // Whenever a Sliver you control attacks, defending player loses 1 life. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new LoseLifeDefendingPlayerEffect(1), false, filter)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new LoseLifeDefendingPlayerEffect(1), false, filter)); } public LeechingSliver(final LeechingSliver card) { diff --git a/Mage.Sets/src/mage/sets/morningtide/RageForger.java b/Mage.Sets/src/mage/sets/morningtide/RageForger.java index 769eb869399..3871fe576b3 100644 --- a/Mage.Sets/src/mage/sets/morningtide/RageForger.java +++ b/Mage.Sets/src/mage/sets/morningtide/RageForger.java @@ -30,7 +30,7 @@ package mage.sets.morningtide; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect; @@ -80,7 +80,7 @@ public class RageForger extends CardImpl { // When Rage Forger enters the battlefield, put a +1/+1 counter on each other Shaman creature you control. this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false)); // Whenever a creature you control with a +1/+1 counter on it attacks, you may have that creature deal 1 damage to target player. - Ability ability = new AttacksCreatureYourControlTriggeredAbility(new RageForgerDamageEffect(), true, filterAttack, true); + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new RageForgerDamageEffect(), true, filterAttack, true); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/morningtide/SharedAnimosity.java b/Mage.Sets/src/mage/sets/morningtide/SharedAnimosity.java index b1acfb0c1e3..b19d1690d3f 100644 --- a/Mage.Sets/src/mage/sets/morningtide/SharedAnimosity.java +++ b/Mage.Sets/src/mage/sets/morningtide/SharedAnimosity.java @@ -35,7 +35,7 @@ import mage.constants.Rarity; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.ChangelingAbility; import mage.cards.CardImpl; @@ -65,7 +65,7 @@ public class SharedAnimosity extends CardImpl { this.color.setRed(true); // Whenever a creature you control attacks, it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new SharedAnimosityEffect(), false, true)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new SharedAnimosityEffect(), false, true)); } public SharedAnimosity(final SharedAnimosity card) { diff --git a/Mage.Sets/src/mage/sets/returntoravnica/UtvaraHellkite.java b/Mage.Sets/src/mage/sets/returntoravnica/UtvaraHellkite.java index 4d8edacf484..333a990e6c2 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/UtvaraHellkite.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/UtvaraHellkite.java @@ -32,7 +32,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -64,7 +64,7 @@ public class UtvaraHellkite extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever a Dragon you control attacks, put a 6/6 red Dragon creature token with flying onto the battlefield. - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new CreateTokenEffect(new UtvaraHellkiteDragonToken()),false, filter)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new CreateTokenEffect(new UtvaraHellkiteDragonToken()),false, filter)); } public UtvaraHellkite(final UtvaraHellkite card) { diff --git a/Mage.Sets/src/mage/sets/theros/KragmaWarcaller.java b/Mage.Sets/src/mage/sets/theros/KragmaWarcaller.java index 3f86db9ce63..b2d6e84b7d3 100644 --- a/Mage.Sets/src/mage/sets/theros/KragmaWarcaller.java +++ b/Mage.Sets/src/mage/sets/theros/KragmaWarcaller.java @@ -29,7 +29,7 @@ package mage.sets.theros; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continious.BoostTargetEffect; @@ -72,7 +72,7 @@ public class KragmaWarcaller extends CardImpl { // Whenever a Minotaur you control attacks, it gets +2/+0 until end of turn. Effect effect = new BoostTargetEffect(2,0, Duration.EndOfTurn); effect.setText("it gets +2/+0 until end of turn"); - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(effect, false, filter1, true)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(effect, false, filter1, true)); } public KragmaWarcaller(final KragmaWarcaller card) { diff --git a/Mage.Sets/src/mage/sets/timespiral/StonebrowKrosanHero.java b/Mage.Sets/src/mage/sets/timespiral/StonebrowKrosanHero.java index 1f788d2b54a..dbc200132c7 100644 --- a/Mage.Sets/src/mage/sets/timespiral/StonebrowKrosanHero.java +++ b/Mage.Sets/src/mage/sets/timespiral/StonebrowKrosanHero.java @@ -29,7 +29,7 @@ package mage.sets.timespiral; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continious.BoostTargetEffect; import mage.abilities.keyword.TrampleAbility; @@ -69,7 +69,7 @@ public class StonebrowKrosanHero extends CardImpl { // Whenever a creature you control with trample attacks, it gets +2/+2 until end of turn. Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); effect.setText("it gets +2/+2 until end of turn"); - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(effect, false, filter, true)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(effect, false, filter, true)); } public StonebrowKrosanHero(final StonebrowKrosanHero card) { diff --git a/Mage.Sets/src/mage/sets/zendikar/BeastmasterAscension.java b/Mage.Sets/src/mage/sets/zendikar/BeastmasterAscension.java index 3d61458b536..a7a136d0e44 100644 --- a/Mage.Sets/src/mage/sets/zendikar/BeastmasterAscension.java +++ b/Mage.Sets/src/mage/sets/zendikar/BeastmasterAscension.java @@ -33,7 +33,7 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; import mage.abilities.Ability; -import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continious.BoostControlledEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; @@ -55,7 +55,7 @@ public class BeastmasterAscension extends CardImpl { this.expansionSetCode = "ZEN"; this.color.setGreen(true); - this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new AddCountersSourceEffect(CounterType.QUEST.createInstance()), true)); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new AddCountersSourceEffect(CounterType.QUEST.createInstance()), true)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BeastmasterAscensionEffect())); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java index 7d6ac1c47fb..8ec19f6c964 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java @@ -127,10 +127,12 @@ public class CloudshiftTest extends CardTestPlayerBase { @Test public void testThatCardIsHandledAsNewInstanceAfterCloudshift() { + // Whenever another creature enters the battlefield under your control, you gain life equal to that creature's toughness. + // {1}{G}{W}, {T}: Populate. (Put a token onto the battlefield that's a copy of a creature token you control.) addCard(Zone.BATTLEFIELD, playerA, "Trostani, Selesnya's Voice"); addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); - addCard(Zone.HAND, playerA, "Grizzly Bears"); + addCard(Zone.HAND, playerA, "Grizzly Bears"); // 2/2 addCard(Zone.HAND, playerA, "Giant Growth"); addCard(Zone.HAND, playerA, "Cloudshift"); @@ -142,7 +144,7 @@ public class CloudshiftTest extends CardTestPlayerBase { execute(); - assertLife(playerA, 27); + assertLife(playerA, 27); // 5 from the first with Giant Growth + 2 from the second bear. } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java index 1ef15dc5ca1..e71f2fd4324 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java @@ -182,7 +182,7 @@ public class BestowTest extends CardTestPlayerBase { * http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/513828-bestow-far-away */ @Test - @Ignore + @Ignore // Handling of targets of Fused spells is not handled yet in TestPlayer class public void bestowWithFusedSpell() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); /** diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/ShowstopperTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/ShowstopperTest.java new file mode 100644 index 00000000000..faa5ba814e2 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/ShowstopperTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.triggers.dies; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ + +public class ShowstopperTest extends CardTestPlayerBase { + + /** + * Tests that the dies triggered ability of silvercoat lion (gained by Showstopper) + * triggers as he dies from Ligning Bolt + * + */ + @Test + public void testDiesTriggeredAbility() { + // Showstopper Instant {1}{B}{R} + // Until end of turn, creatures you control gain "When this creature dies, it deals 2 damage to target creature an opponent controls." + addCard(Zone.HAND, playerA, "Showstopper"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + addCard(Zone.HAND, playerA, "Lightning Bolt"); + addCard(Zone.BATTLEFIELD, playerB, "Ornithopter", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Showstopper"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, "Showstopper", 1); + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + + assertGraveyardCount(playerB, "Ornithopter", 1); + } + /** + * Test if Showstopper is called twice + */ + + @Test + public void testTwoDiesTriggeredAbilities() { + // Showstopper Instant {1}{B}{R} + // Until end of turn, creatures you control gain "When this creature dies, it deals 2 damage to target creature an opponent controls." + addCard(Zone.HAND, playerA, "Showstopper", 2); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + addCard(Zone.HAND, playerB, "Lightning Bolt"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerB, "Ornithopter", 1); + addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Showstopper"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Showstopper"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion"); + addTarget(playerA, "Ornithopter"); + addTarget(playerA, "Grizzly Bears"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, "Showstopper", 2); + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + + assertGraveyardCount(playerB, "Grizzly Bears", 1); + assertGraveyardCount(playerB, "Ornithopter", 1); + } + +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/WhisperwoodElementalTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/WhisperwoodElementalTest.java new file mode 100644 index 00000000000..1f967f23ca8 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/WhisperwoodElementalTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.triggers.dies; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * Whisperwood Elemental - Elemental {3}{G}{G} + * At the beginning of your end step, manifest the top card of your library. + * Sacrifice Whisperwood Elemental: Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library." + * + * @author LevelX2 + */ +public class WhisperwoodElementalTest extends CardTestPlayerBase { + + /** + * Tests that the dies triggered ability of silvercoat lion (gained by sacrificed Whisperwood Elemental) + * triggers as he dies from Ligning Bolt + * + */ + @Test + public void testDiesTriggeredAbility() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, "Whisperwood Elemental", 1); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + addCard(Zone.HAND, playerA, "Lightning Bolt"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Until end of turn, face-up, nontoken creatures you control gain \"When this creature dies, manifest the top card of your library."); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, "Whisperwood Elemental", 1); + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + + // Manifested creature from dying Silvercoat Lion + assertPermanentCount(playerA, "face down creature", 1); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/combat/DamageDistributionTest.java b/Mage.Tests/src/test/java/org/mage/test/combat/DamageDistributionTest.java index 53efa803920..68d646ae406 100644 --- a/Mage.Tests/src/test/java/org/mage/test/combat/DamageDistributionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/combat/DamageDistributionTest.java @@ -94,7 +94,6 @@ public class DamageDistributionTest extends CardTestPlayerBase { */ @Test - //@Ignore public void testDoubleStrikeTrampleVersusIndestructibleGod() { /** * Heliod, God of the Sun diff --git a/Mage/src/mage/MageObjectReference.java b/Mage/src/mage/MageObjectReference.java index 48154266d74..7033489927c 100644 --- a/Mage/src/mage/MageObjectReference.java +++ b/Mage/src/mage/MageObjectReference.java @@ -128,6 +128,14 @@ public class MageObjectReference implements Comparable { return null; } + public Permanent getPermanentOrLKIBattlefield(Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(sourceId); + if (permanent != null && permanent.getZoneChangeCounter() == zoneChangeCounter) { + return permanent; + } + return null; + } + public Card getCard(Game game) { Card card = game.getCard(sourceId); if (card != null && card.getZoneChangeCounter() == zoneChangeCounter) { diff --git a/Mage/src/mage/abilities/common/AttacksCreatureYourControlTriggeredAbility.java b/Mage/src/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java similarity index 79% rename from Mage/src/mage/abilities/common/AttacksCreatureYourControlTriggeredAbility.java rename to Mage/src/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 75f5cd21150..db96a2024c3 100644 --- a/Mage/src/mage/abilities/common/AttacksCreatureYourControlTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -28,9 +28,9 @@ package mage.abilities.common; -import mage.constants.Zone; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -41,34 +41,34 @@ import mage.target.targetpointer.FixedTarget; * * @author noxx */ -public class AttacksCreatureYourControlTriggeredAbility extends TriggeredAbilityImpl { +public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityImpl { protected FilterControlledCreaturePermanent filter; protected boolean setTargetPointer; - public AttacksCreatureYourControlTriggeredAbility(Effect effect) { + public AttacksCreatureYouControlTriggeredAbility(Effect effect) { this(effect, false); } - public AttacksCreatureYourControlTriggeredAbility(Effect effect, boolean optional) { + public AttacksCreatureYouControlTriggeredAbility(Effect effect, boolean optional) { this(effect, optional, new FilterControlledCreaturePermanent()); } - public AttacksCreatureYourControlTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { + public AttacksCreatureYouControlTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { this(effect, optional, new FilterControlledCreaturePermanent(), setTargetPointer); } - public AttacksCreatureYourControlTriggeredAbility(Effect effect, boolean optional, FilterControlledCreaturePermanent filter) { + public AttacksCreatureYouControlTriggeredAbility(Effect effect, boolean optional, FilterControlledCreaturePermanent filter) { this(effect, optional, filter, false); } - public AttacksCreatureYourControlTriggeredAbility(Effect effect, boolean optional, FilterControlledCreaturePermanent filter, boolean setTargetPointer) { + public AttacksCreatureYouControlTriggeredAbility(Effect effect, boolean optional, FilterControlledCreaturePermanent filter, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); this.filter = filter; this.setTargetPointer = setTargetPointer; } - public AttacksCreatureYourControlTriggeredAbility(AttacksCreatureYourControlTriggeredAbility ability) { + public AttacksCreatureYouControlTriggeredAbility(AttacksCreatureYouControlTriggeredAbility ability) { super(ability); this.filter = ability.filter; this.setTargetPointer = ability.setTargetPointer; @@ -91,8 +91,8 @@ public class AttacksCreatureYourControlTriggeredAbility extends TriggeredAbility } @Override - public AttacksCreatureYourControlTriggeredAbility copy() { - return new AttacksCreatureYourControlTriggeredAbility(this); + public AttacksCreatureYouControlTriggeredAbility copy() { + return new AttacksCreatureYouControlTriggeredAbility(this); } @Override diff --git a/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java b/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java index 983cb1d2f90..0a926d9ff63 100644 --- a/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java @@ -30,13 +30,14 @@ package mage.abilities.effects.common.continious; import java.util.Iterator; import mage.MageObjectReference; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.abilities.Ability; import mage.abilities.CompoundAbility; import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.SubLayer; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -106,20 +107,23 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { if (this.affectedObjectsSet) { for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost - Permanent perm = it.next().getPermanent(game); + Permanent perm = it.next().getPermanentOrLKIBattlefield(game); //LKI is neccessary for "dies triggered abilities" to work given to permanets (e.g. Showstopper) if (perm != null) { for (Ability abilityToAdd : ability) { - perm.addAbility(abilityToAdd, source.getSourceId(), game); + perm.addAbility(abilityToAdd, source.getSourceId(), game, false); // new id is neccessary if } } else { - it.remove(); // no longer on the battlefield, remove reference to object + it.remove(); + if (affectedObjectList.isEmpty()) { + discard(); + } } } } else { for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { if (!(excludeSource && perm.getId().equals(source.getSourceId()))) { for (Ability abilityToAdd : ability) { - perm.addAbility(abilityToAdd, source.getSourceId(), game); + perm.addAbility(abilityToAdd, source.getSourceId(), game, false); } } } diff --git a/Mage/src/mage/abilities/effects/common/continious/GainControlTargetEffect.java b/Mage/src/mage/abilities/effects/common/continious/GainControlTargetEffect.java index 43e9764b198..84bf142c2c9 100644 --- a/Mage/src/mage/abilities/effects/common/continious/GainControlTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/GainControlTargetEffect.java @@ -131,7 +131,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl { return staticText; } Target target = mode.getTargets().get(0); - StringBuilder sb = new StringBuilder("Gain control of "); + StringBuilder sb = new StringBuilder("gain control of "); if (target.getMaxNumberOfTargets() > 1){ if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) { sb.append("up to "); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 83b777ba94e..af4e96fc8bd 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -2191,6 +2191,11 @@ public abstract class GameImpl implements Game, Serializable { return getLastKnownInformation(objectId, zone); } + @Override + public Map getLastKnownInformation(Zone zone) { + return lki.get(zone); + } + @Override public MageObject getShortLivingLKI(UUID objectId, Zone zone) { Map shortLivingLkiMap = shortLivingLKI.get(zone); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 2b6ab80f4c4..1473de600fa 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -220,6 +220,15 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { copyAbility.setSourceId(objectId); game.getState().addAbility(copyAbility, sourceId, this); abilities.add(copyAbility); + } else if (!createNewId) { + // triggered abilities must be added to the state().triggerdAbilities + // still as long as the prev. permanent is known to the LKI (e.g. Showstopper) so gained dies triggered ability will trigger + if (!game.getBattlefield().containsPermanent(this.getId())) { + Ability copyAbility = ability.copy(); + copyAbility.setControllerId(controllerId); + copyAbility.setSourceId(objectId); + game.getState().addAbility(copyAbility, sourceId, this); + } } }