diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/RenegadeKrasis.java b/Mage.Sets/src/mage/sets/dragonsmaze/RenegadeKrasis.java index 6bd8f47bef..32b2b81941 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/RenegadeKrasis.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/RenegadeKrasis.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.dragonsmaze; import java.util.UUID; @@ -44,13 +43,10 @@ import mage.filter.predicate.permanent.CounterPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.stack.StackObject; - - public class RenegadeKrasis extends CardImpl { - public RenegadeKrasis (UUID ownerId) { + public RenegadeKrasis(UUID ownerId) { super(ownerId, 47, "Renegade Krasis", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); this.expansionSetCode = "DGM"; this.subtype.add("Beast"); @@ -66,7 +62,7 @@ public class RenegadeKrasis extends CardImpl { this.addAbility(new RenegadeKrasisTriggeredAbility()); } - public RenegadeKrasis (final RenegadeKrasis card) { + public RenegadeKrasis(final RenegadeKrasis card) { super(card); } @@ -80,13 +76,14 @@ public class RenegadeKrasis extends CardImpl { class RenegadeKrasisTriggeredAbility extends TriggeredAbilityImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + static { filter.add(new AnotherPredicate()); filter.add(new CounterPredicate(CounterType.P1P1)); } public RenegadeKrasisTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(1),filter), false); + super(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(1), filter), false); } public RenegadeKrasisTriggeredAbility(final RenegadeKrasisTriggeredAbility ability) { @@ -100,31 +97,16 @@ class RenegadeKrasisTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.COUNTER_ADDED; + return event.getType() == EventType.EVOLVED_CREATURE; } @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(getSourceId())) { - Object object = game.getState().getValue("EvolveAddCounterActive"); - if (object != null && (Boolean) object) { - StackObject stackObject = game.getStack().getLast(); - if (stackObject.getStackAbility() instanceof EvolveAbility) { - object = game.getState().getValue(this.getId() + "_lastUsedEvolveStackObject"); - if (object != null && ((UUID) object).equals(stackObject.getId())) { - // this evolve was already handled before (prevents to trigger multiple times if counter from evolve is e.g. doubled) - return false; - } - game.getState().setValue(this.getId() + "_lastUsedEvolveStackObject", stackObject.getId()); - return true; - } - } - } - return false; + return event.getTargetId().equals(getSourceId()); } @Override public String getRule() { - return "Whenever Renegade Krasis evolves, put a +1/+1 counter on each other creature you control with a +1/+1 counter on it."; + return "Whenever {this} evolves, put a +1/+1 counter on each other creature you control with a +1/+1 counter on it."; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EvolveTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EvolveTest.java index 3472d6e139..6aad4cc47e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EvolveTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EvolveTest.java @@ -25,11 +25,11 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package org.mage.test.cards.abilities.keywords; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.filter.Filter; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -37,15 +37,12 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - - public class EvolveTest extends CardTestPlayerBase { @Test public void testCreatureComesIntoPlay() { // Cloudfin Raptor gets one +1/+1 because Mindeye Drake comes into play - addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.BATTLEFIELD, playerA, "Cloudfin Raptor", 1); @@ -70,7 +67,6 @@ public class EvolveTest extends CardTestPlayerBase { public void testCreatureComesIntoPlayNoCounter() { // Experiment One gets no counter because Kird Ape is 1/1 with no Forest in play - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerA, "Experiment One", 1); @@ -95,7 +91,6 @@ public class EvolveTest extends CardTestPlayerBase { public void testCreatureComesStrongerIntoPlayCounter() { // Experiment One gets a counter because Kird Ape is 2/2 with a Forest in play - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Experiment One", 1); @@ -121,7 +116,6 @@ public class EvolveTest extends CardTestPlayerBase { public void testEvolveWithMasterBiomance() { // Experiment One gets a counter because Kird Ape is 2/2 with a Forest in play - addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Experiment One", 1); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); @@ -145,20 +139,18 @@ public class EvolveTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Experiment One", 3, 3); } - + @Test public void testMultipleCreaturesComeIntoPlay() { // Cloudfin Raptor gets one +1/+1 because itself and other creatur return from exile - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); addCard(Zone.BATTLEFIELD, playerA, "Judge's Familiar", 1); addCard(Zone.BATTLEFIELD, playerA, "Cloudfin Raptor", 1); addCard(Zone.HAND, playerA, "Mizzium Mortars", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Plains", 6); addCard(Zone.HAND, playerB, "Banisher Priest", 2); - castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banisher Priest"); addTarget(playerB, "Cloudfin Raptor"); @@ -174,7 +166,7 @@ public class EvolveTest extends CardTestPlayerBase { assertLife(playerB, 20); assertPermanentCount(playerB, "Banisher Priest", 0); - + assertGraveyardCount(playerB, 2); assertGraveyardCount(playerA, 1); @@ -182,26 +174,22 @@ public class EvolveTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Judge's Familiar", 1); assertPowerToughness(playerA, "Cloudfin Raptor", 1, 2); - - - } - + + } + @Test public void testMultipleCreaturesComeIntoPlaySuddenDisappearance() { // Sudden Disappearance // Sorcery {5}{W} - // Exile all nonland permanents target player controls. Return the exiled cards + // Exile all nonland permanents target player controls. Return the exiled cards // to the battlefield under their owner's control at the beginning of the next end step. - // Battering Krasis (2/1) and Crocanura (1/3) get both a +1/+1 counter each other because they come into play at the same time - addCard(Zone.BATTLEFIELD, playerA, "Battering Krasis", 1); addCard(Zone.BATTLEFIELD, playerA, "Crocanura", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Plains", 6); addCard(Zone.HAND, playerB, "Sudden Disappearance", 2); - castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Sudden Disappearance", playerA); @@ -210,7 +198,7 @@ public class EvolveTest extends CardTestPlayerBase { assertLife(playerA, 20); assertLife(playerB, 20); - + assertGraveyardCount(playerB, 1); assertGraveyardCount(playerA, 0); @@ -219,9 +207,58 @@ public class EvolveTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Battering Krasis", 3, 2); assertPowerToughness(playerA, "Crocanura", 2, 4); - - - } - - + + } + + /* + * Renegade Krasis's ability when trigger it evolves is not triggered under + * case. + * + * I control Renegade Krasis and two Ivy Lane Denizen. (Renegade Krasis and + * one of Ivy Lane Denizen have a +1/+1 counter on it) + * I cast Adaptive Snapjaw. + * When it resolves, there are three abilities on going to stack, + * Renegade Krasis's Evolve Ability, two Ivy Lane Denizen ability. + * I take two Ivy Lane Denizen on to the stack and then Renegade Krasis's Evolve + * Ability, so resolving Renegade Krasis's Evolve Ability is first . (Maybe + * Ivy Lane Denizen's target is any.) When Renegade Krasis's Evolve Ability + * resolves, +1/+1 counter is placed on it, but doesn't triggers Renegade + * Krasis's second ability. + */ + @Test + public void testRenegadeKrasis() { + + // Evolve (Whenever a creature enters the battlefield under your control, if that creature has greater power or toughness + // than this creature, put a +1/+1 counter on this creature.) + // Whenever Renegade Krasis evolves, put a +1/+1 counter on each other creature you control with a +1/+1 counter on it. + addCard(Zone.BATTLEFIELD, playerA, "Renegade Krasis", 1); // 3/2 + addCard(Zone.BATTLEFIELD, playerA, "Ivy Lane Denizen", 1); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 9); + + // Whenever another green creature enters the battlefield under your control, put a +1/+1 counter on target creature. + addCard(Zone.HAND, playerA, "Ivy Lane Denizen", 1); // {3}{G} - Creature 2/3 + // Evolve + addCard(Zone.HAND, playerA, "Adaptive Snapjaw", 1); // {4}{G} - Creature 6/2 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ivy Lane Denizen"); + addTarget(playerA, "Ivy Lane Denizen"); + setChoice(playerA, "Evolve"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Adaptive Snapjaw"); + addTarget(playerA, "Adaptive Snapjaw"); + addTarget(playerA, "Adaptive Snapjaw"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Renegade Krasis", 1); + assertPermanentCount(playerA, "Ivy Lane Denizen", 2); + assertPermanentCount(playerA, "Adaptive Snapjaw", 1); + + assertPowerToughness(playerA, "Adaptive Snapjaw", 9, 5); // +2 from Ivys +1 from add to all with +1/+1 counter + assertPowerToughness(playerA, "Renegade Krasis", 5, 4); // +1 Evolve by Ivy +1 Evolve by Snapjaw + assertPowerToughness(playerA, "Ivy Lane Denizen", 2, 3, Filter.ComparisonScope.Any); + assertPowerToughness(playerA, "Ivy Lane Denizen", 5, 6, Filter.ComparisonScope.Any); // +1 from Other Ivy + 2 from Krasis + + } } diff --git a/Mage/src/mage/abilities/effects/common/counter/AddCountersAllEffect.java b/Mage/src/mage/abilities/effects/common/counter/AddCountersAllEffect.java index a818747e8e..709eb78698 100644 --- a/Mage/src/mage/abilities/effects/common/counter/AddCountersAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/counter/AddCountersAllEffect.java @@ -27,12 +27,10 @@ */ package mage.abilities.effects.common.counter; -import java.util.List; -import java.util.UUID; import mage.MageObject; -import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.counters.Counter; import mage.filter.FilterPermanent; import mage.game.Game; @@ -67,21 +65,16 @@ public class AddCountersAllEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { if (counter != null) { - UUID controllerId = source.getControllerId(); - List permanents = game.getBattlefield().getAllActivePermanents(); - for (Permanent permanent : permanents) { - if (filter.match(permanent, source.getSourceId(), controllerId, game)) { - permanent.addCounters(counter.copy(), game); - if (!game.isSimulation()) - game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ") - .append(controller.getLogName()).append(" puts ") - .append(counter.getCount()).append(" ").append(counter.getName().toLowerCase()) - .append(" counter on ").append(permanent.getName()).toString()); + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + permanent.addCounters(counter.copy(), game); + if (!game.isSimulation()) { + game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " puts " + counter.getCount() + " " + counter.getName().toLowerCase() + + " counter on " + permanent.getLogName()); } } - } + } return true; - } + } return false; } diff --git a/Mage/src/mage/abilities/keyword/EvolveAbility.java b/Mage/src/mage/abilities/keyword/EvolveAbility.java index 00712d973c..a23e25143b 100644 --- a/Mage/src/mage/abilities/keyword/EvolveAbility.java +++ b/Mage/src/mage/abilities/keyword/EvolveAbility.java @@ -166,9 +166,8 @@ class EvolveEffect extends OneShotEffect { if (triggeringCreature != null) { Permanent sourceCreature = game.getPermanent(source.getSourceId()); if (sourceCreature != null && EvolveAbility.isPowerOrThoughnessGreater(sourceCreature, triggeringCreature)) { - game.getState().setValue("EvolveAddCounterActive", Boolean.TRUE); sourceCreature.addCounters(CounterType.P1P1.createInstance(), game); - game.getState().setValue("EvolveAddCounterActive", Boolean.FALSE); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EVOLVED_CREATURE, sourceCreature.getId(), source.getSourceId(), source.getControllerId())); } return true; } diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index 38e9ebeefe..6b96c0a15a 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -214,6 +214,7 @@ public class GameEvent implements Serializable { SACRIFICE_PERMANENT, SACRIFICED_PERMANENT, FIGHTED_PERMANENT, EXPLOITED_CREATURE, + EVOLVED_CREATURE, ATTACH, ATTACHED, UNATTACH, UNATTACHED, ADD_COUNTER, COUNTER_ADDED,