diff --git a/Mage.Sets/src/mage/cards/m/MatopiGolem.java b/Mage.Sets/src/mage/cards/m/MatopiGolem.java new file mode 100644 index 00000000000..09a738b8f4d --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MatopiGolem.java @@ -0,0 +1,47 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.RegenerateSourceWithReflexiveEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class MatopiGolem extends CardImpl { + + public MatopiGolem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + + this.subtype.add(SubType.GOLEM); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {1}: Regenerate Matopi Golem. When it regenerates this way, put a -1/-1 counter on it. + this.addAbility(new SimpleActivatedAbility( + new RegenerateSourceWithReflexiveEffect(new ReflexiveTriggeredAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance()), + false + ), false), + new GenericManaCost(1) + )); + } + + private MatopiGolem(final MatopiGolem card) { + super(card); + } + + @Override + public MatopiGolem copy() { + return new MatopiGolem(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java b/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java index 9e39e163754..88715bd0193 100644 --- a/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java +++ b/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java @@ -4,21 +4,19 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.RegenerateSourceWithReflexiveEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.counters.CounterType; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.ManaUtil; @@ -40,7 +38,13 @@ public final class SkeletonScavengers extends CardImpl { this.addAbility(new AsEntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))); // Pay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it. - this.addAbility(new SimpleActivatedAbility(new SkeletonScavengersEffect(), new DynamicValueGenericManaCost(new CountersSourceCount(CounterType.P1P1)))); + this.addAbility(new SimpleActivatedAbility( + new RegenerateSourceWithReflexiveEffect(new ReflexiveTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), + false + ), false), + new DynamicValueGenericManaCost(new CountersSourceCount(CounterType.P1P1)) + )); } @@ -99,32 +103,4 @@ class DynamicValueGenericManaCost extends CostImpl { private void setText() { text = ("Pay {1} for each +1/+1 counter on {this}"); } -} - -class SkeletonScavengersEffect extends OneShotEffect { - - SkeletonScavengersEffect() { - super(Outcome.Benefit); - this.staticText = "Regenerate {this}. When it regenerates this way, put a +1/+1 counter on it"; - } - - private SkeletonScavengersEffect(final SkeletonScavengersEffect effect) { - super(effect); - } - - @Override - public SkeletonScavengersEffect copy() { - return new SkeletonScavengersEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent skeletonScavengers = game.getPermanent(source.getSourceId()); - if (skeletonScavengers != null) { - if (new RegenerateSourceEffect().apply(game, source)) { - return new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source); - } - } - return false; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SoldeviSentry.java b/Mage.Sets/src/mage/cards/s/SoldeviSentry.java index 591db5853b2..a6ce6342c42 100644 --- a/Mage.Sets/src/mage/cards/s/SoldeviSentry.java +++ b/Mage.Sets/src/mage/cards/s/SoldeviSentry.java @@ -3,16 +3,14 @@ package mage.cards.s; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.RegenerateSourceWithReflexiveEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetOpponent; import java.util.UUID; @@ -28,9 +26,16 @@ public final class SoldeviSentry extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - // 1: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates - // this way, that player may draw a card. - Ability ability = new SimpleActivatedAbility(new SoldeviSentryEffect(), new GenericManaCost(1)); + // {1}: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates this way, that player may draw a card. + Ability ability = new SimpleActivatedAbility( + new RegenerateSourceWithReflexiveEffect(new ReflexiveTriggeredAbility( + new DrawCardTargetEffect(1, true), + false + ), true) + .setText("Choose target opponent. Regenerate Soldevi Sentry. " + + "When it regenerates this way, that player may draw a card"), + new GenericManaCost(1) + ); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } @@ -43,39 +48,4 @@ public final class SoldeviSentry extends CardImpl { public SoldeviSentry copy() { return new SoldeviSentry(this); } -} - -class SoldeviSentryEffect extends RegenerateSourceEffect { - - public SoldeviSentryEffect() { - super(); - this.staticText = "Choose target opponent. Regenerate {this}. When it regenerates this way, that player may draw a card"; - } - - protected SoldeviSentryEffect(final SoldeviSentryEffect effect) { - super(effect); - } - - @Override - public SoldeviSentryEffect copy() { - return new SoldeviSentryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - //20110204 - 701.11 - Player opponent = game.getPlayer(source.getFirstTarget()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && permanent.regenerate(source, game)) { - if (opponent != null) { - if (opponent.chooseUse(Outcome.DrawCard, "Draw a card?", source, game)) { - opponent.drawCards(1, source, game); - } - } - this.used = true; - return true; - } - return false; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 02ead5767b1..09bb65f5940 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -107,6 +107,7 @@ public final class Visions extends ExpansionSet { cards.add(new SetCardInfo("Longbow Archer", 12, Rarity.UNCOMMON, mage.cards.l.LongbowArcher.class)); cards.add(new SetCardInfo("Magma Mine", 149, Rarity.UNCOMMON, mage.cards.m.MagmaMine.class)); cards.add(new SetCardInfo("Man-o'-War", 37, Rarity.COMMON, mage.cards.m.ManOWar.class)); + cards.add(new SetCardInfo("Matopi Golem", 150, Rarity.UNCOMMON, mage.cards.m.MatopiGolem.class)); cards.add(new SetCardInfo("Miraculous Recovery", 13, Rarity.UNCOMMON, mage.cards.m.MiraculousRecovery.class)); cards.add(new SetCardInfo("Mob Mentality", 88, Rarity.UNCOMMON, mage.cards.m.MobMentality.class)); cards.add(new SetCardInfo("Mortal Wound", 113, Rarity.COMMON, mage.cards.m.MortalWound.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/all/SoldeviSentryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/all/SoldeviSentryTest.java new file mode 100644 index 00000000000..313afbe898a --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/all/SoldeviSentryTest.java @@ -0,0 +1,40 @@ +package org.mage.test.cards.single.all; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class SoldeviSentryTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.s.SoldeviSentry}
+ * Soldevi Sentry {1}
+ * Artifact Creature — Soldier
+ * {1}: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates this way, that player may draw a card.
+ * 1/1 + */ + private static final String sentry = "Soldevi Sentry"; + + @Test + public void test_ReflexiveOnRegenerate() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, sentry); + addCard(Zone.HAND, playerA, "Doom Blade"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + + activateAbility(1, PhaseStep.UPKEEP, playerA, "{1}: Choose", playerB); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", sentry); + setChoice(playerB, true); // yes to drawing a card in the reflexive trigger + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, sentry, 1); + assertTapped(sentry, true); + assertHandCount(playerB, 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/vis/MatopiGolemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/vis/MatopiGolemTest.java new file mode 100644 index 00000000000..3baa84f7d20 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/vis/MatopiGolemTest.java @@ -0,0 +1,39 @@ +package org.mage.test.cards.single.vis; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Susucr + */ +public class MatopiGolemTest extends CardTestPlayerBase { + + /** + * {@link mage.cards.m.MatopiGolem}
+ * Matopi Golem {5}
+ * Artifact Creature — Golem
+ * {1}: Regenerate Matopi Golem. When it regenerates this way, put a -1/-1 counter on it.
+ * 3/3 + */ + private static final String golem = "Matopi Golem"; + + @Test + public void test_ReflexiveOnRegenerate() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, golem); + addCard(Zone.HAND, playerA, "Doom Blade"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + + activateAbility(1, PhaseStep.UPKEEP, playerA, "{1}: Regenerate"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", golem); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, golem, 1); + assertTapped(golem, true); + assertPowerToughness(playerA, golem, 3 - 1, 3 - 1); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/RegenerateSourceWithReflexiveEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RegenerateSourceWithReflexiveEffect.java new file mode 100644 index 00000000000..216ff027448 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/RegenerateSourceWithReflexiveEffect.java @@ -0,0 +1,49 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.game.Game; +import mage.target.targetpointer.FixedTarget; + +/** + * @author Susucr + */ +public class RegenerateSourceWithReflexiveEffect extends RegenerateSourceEffect { + + private final ReflexiveTriggeredAbility reflexive; + private final boolean setReflexiveTarget; + + public RegenerateSourceWithReflexiveEffect(ReflexiveTriggeredAbility reflexive, boolean setReflexiveTarget) { + super(); + this.reflexive = reflexive; + this.reflexive.setTriggerPhrase("When it regenerates this way, "); + this.setReflexiveTarget = setReflexiveTarget; + this.staticText = "regenerate {this}. " + reflexive.getRule(); + } + + protected RegenerateSourceWithReflexiveEffect(final RegenerateSourceWithReflexiveEffect effect) { + super(effect); + this.reflexive = effect.reflexive.copy(); + this.setReflexiveTarget = effect.setReflexiveTarget; + } + + @Override + public RegenerateSourceWithReflexiveEffect copy() { + return new RegenerateSourceWithReflexiveEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (super.apply(game, source)) { + if (this.setReflexiveTarget) { + reflexive.getEffects().setTargetPointer( + new FixedTarget(targetPointer.getFirst(game, source), game) + ); + } + game.fireReflexiveTriggeredAbility(reflexive, source); + return true; + } + return false; + } + +} \ No newline at end of file