forked from External/mage
[MKC] Implement Serene Sleuth
This commit is contained in:
parent
78694fce0b
commit
8656548676
3 changed files with 228 additions and 0 deletions
132
Mage.Sets/src/mage/cards/s/SereneSleuth.java
Normal file
132
Mage.Sets/src/mage/cards/s/SereneSleuth.java
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObjectReference;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
|
||||||
|
import mage.abilities.effects.ContinuousEffect;
|
||||||
|
import mage.abilities.effects.ContinuousEffectImpl;
|
||||||
|
import mage.abilities.effects.keyword.InvestigateEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.*;
|
||||||
|
import mage.filter.FilterPermanent;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.permanent.GoadedPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public final class SereneSleuth extends CardImpl {
|
||||||
|
|
||||||
|
private final static FilterPermanent filter = new FilterControlledCreaturePermanent("goaded creatures you control");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(GoadedPredicate.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SereneSleuth(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.subtype.add(SubType.DETECTIVE);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// When Serene Sleuth enters the battlefield, investigate.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvestigateEffect()));
|
||||||
|
|
||||||
|
// At the beginning of combat on your turn, investigate for each goaded creature you control. Then each creature you control is no longer goaded.
|
||||||
|
Ability triggeredAbility = new BeginningOfCombatTriggeredAbility(
|
||||||
|
new InvestigateEffect(new PermanentsOnBattlefieldCount(filter))
|
||||||
|
.setText("investigate for each goaded creature you control.")
|
||||||
|
);
|
||||||
|
triggeredAbility.addEffect(new SereneSleuthEffect(filter)
|
||||||
|
.concatBy("Then"));
|
||||||
|
this.addAbility(triggeredAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SereneSleuth(final SereneSleuth card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SereneSleuth copy() {
|
||||||
|
return new SereneSleuth(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SereneSleuthEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
|
private MageObjectReference sourceMor;
|
||||||
|
private final FilterPermanent filter;
|
||||||
|
|
||||||
|
public SereneSleuthEffect(FilterPermanent filter) {
|
||||||
|
super(Duration.Custom, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit);
|
||||||
|
staticText = "each creature you control is no longer goaded";
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SereneSleuthEffect(final SereneSleuthEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
this.sourceMor = effect.sourceMor;
|
||||||
|
this.filter = effect.filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SereneSleuthEffect copy() {
|
||||||
|
return new SereneSleuthEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MageObjectReference getSourceMor() {
|
||||||
|
return sourceMor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Ability source, Game game) {
|
||||||
|
super.init(source, game);
|
||||||
|
// discard previous effect if it exists to not clutter
|
||||||
|
for (ContinuousEffect effect : game.getContinuousEffects().getLayeredEffects(game)) {
|
||||||
|
if (effect instanceof SereneSleuthEffect) {
|
||||||
|
MageObjectReference effectsMor = ((SereneSleuthEffect) effect).getSourceMor();
|
||||||
|
if (effectsMor != null && effectsMor.refersTo(source.getSourceId(), game)) {
|
||||||
|
effect.discard();
|
||||||
|
this.affectedObjectList.addAll(effect.getAffectedObjects());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceMor = new MageObjectReference(source.getSourceObject(game), game);
|
||||||
|
setAffectedObjectsSet(true);
|
||||||
|
game.getBattlefield()
|
||||||
|
.getActivePermanents(
|
||||||
|
filter, source.getControllerId(), source, game
|
||||||
|
).stream()
|
||||||
|
.map(permanent -> new MageObjectReference(permanent, game))
|
||||||
|
.forEach(mor -> {
|
||||||
|
if (!this.affectedObjectList.contains(mor)) {
|
||||||
|
this.affectedObjectList.add(mor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
if (getAffectedObjectsSet()) {
|
||||||
|
this.affectedObjectList.removeIf(mor -> !mor.zoneCounterIsCurrent(game)
|
||||||
|
|| mor.getPermanent(game) == null);
|
||||||
|
if (affectedObjectList.isEmpty()) {
|
||||||
|
discard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (MageObjectReference mor : this.affectedObjectList) {
|
||||||
|
mor.getPermanent(game).getGoadingPlayers().clear();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -244,6 +244,9 @@ public final class MurdersAtKarlovManorCommander extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Selesnya Sanctuary", 290, Rarity.UNCOMMON, mage.cards.s.SelesnyaSanctuary.class));
|
cards.add(new SetCardInfo("Selesnya Sanctuary", 290, Rarity.UNCOMMON, mage.cards.s.SelesnyaSanctuary.class));
|
||||||
cards.add(new SetCardInfo("Selfless Squire", 82, Rarity.RARE, mage.cards.s.SelflessSquire.class));
|
cards.add(new SetCardInfo("Selfless Squire", 82, Rarity.RARE, mage.cards.s.SelflessSquire.class));
|
||||||
cards.add(new SetCardInfo("Selvala, Explorer Returned", 218, Rarity.RARE, mage.cards.s.SelvalaExplorerReturned.class));
|
cards.add(new SetCardInfo("Selvala, Explorer Returned", 218, Rarity.RARE, mage.cards.s.SelvalaExplorerReturned.class));
|
||||||
|
cards.add(new SetCardInfo("Serene Sleuth", 14, Rarity.RARE, mage.cards.s.SereneSleuth.class));
|
||||||
|
cards.add(new SetCardInfo("Serene Sleuth", 14, Rarity.RARE, mage.cards.s.SereneSleuth.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Serene Sleuth", 325, Rarity.RARE, mage.cards.s.SereneSleuth.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Sevinne's Reclamation", 83, Rarity.RARE, mage.cards.s.SevinnesReclamation.class));
|
cards.add(new SetCardInfo("Sevinne's Reclamation", 83, Rarity.RARE, mage.cards.s.SevinnesReclamation.class));
|
||||||
cards.add(new SetCardInfo("Sheltered Thicket", 291, Rarity.RARE, mage.cards.s.ShelteredThicket.class));
|
cards.add(new SetCardInfo("Sheltered Thicket", 291, Rarity.RARE, mage.cards.s.ShelteredThicket.class));
|
||||||
cards.add(new SetCardInfo("Shimmer Dragon", 117, Rarity.RARE, mage.cards.s.ShimmerDragon.class));
|
cards.add(new SetCardInfo("Shimmer Dragon", 117, Rarity.RARE, mage.cards.s.ShimmerDragon.class));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
package org.mage.test.cards.single.mkc;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public class SereneSleuthTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serene Sleuth
|
||||||
|
{1}{W}
|
||||||
|
Creature - Human Detective
|
||||||
|
When Serene Sleuth enters the battlefield, investigate.
|
||||||
|
At the beginning of combat on your turn, investigate for each goaded creature you control. Then each creature you control is no longer goaded.
|
||||||
|
2/2
|
||||||
|
*/
|
||||||
|
private static final String sereneSleuth = "Serene Sleuth";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Baeloth Barrityl, Entertainer
|
||||||
|
{4}{R}
|
||||||
|
Legendary Creature - Elf Shaman
|
||||||
|
Creatures your opponents control with power less than Baeloth Barrityl's power are goaded.
|
||||||
|
Whenever a goaded attacking or blocking creature dies, you create a Treasure token.
|
||||||
|
Choose a Background
|
||||||
|
2/5
|
||||||
|
*/
|
||||||
|
private static final String baelothBarritylEntertainer = "Baeloth Barrityl, Entertainer";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fugitive Wizard
|
||||||
|
{U}
|
||||||
|
Creature - Human Wizard
|
||||||
|
|
||||||
|
1/1
|
||||||
|
*/
|
||||||
|
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cloudshift
|
||||||
|
{W}
|
||||||
|
Instant
|
||||||
|
Exile target creature you control, then return that card to the battlefield under your control.
|
||||||
|
*/
|
||||||
|
private static final String cloudshift = "Cloudshift";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSereneSleuth() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, baelothBarritylEntertainer);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, fugitiveWizard);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||||
|
addCard(Zone.HAND, playerA, sereneSleuth);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sereneSleuth);
|
||||||
|
|
||||||
|
setStopAt(3, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, "Clue Token", 1 + 1);
|
||||||
|
assertTrue("fugitive wizard is not goaded", getPermanent(fugitiveWizard).getGoadingPlayers().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSereneSleuthReGoaded() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, baelothBarritylEntertainer);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, fugitiveWizard);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||||
|
addCard(Zone.HAND, playerA, sereneSleuth);
|
||||||
|
addCard(Zone.HAND, playerB, cloudshift);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sereneSleuth);
|
||||||
|
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, cloudshift, baelothBarritylEntertainer);
|
||||||
|
|
||||||
|
setStopAt(3, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, "Clue Token", 1 + 1 + 1);
|
||||||
|
assertTrue("fugitive wizard is goaded", getPermanent(fugitiveWizard).getGoadingPlayers().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue