diff --git a/Mage.Sets/src/mage/cards/s/ShadrixSilverquill.java b/Mage.Sets/src/mage/cards/s/ShadrixSilverquill.java new file mode 100644 index 0000000000..5eb3ea5faf --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShadrixSilverquill.java @@ -0,0 +1,130 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterPlayer; +import mage.filter.StaticFilters; +import mage.filter.predicate.other.AnotherTargetPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SilverquillToken; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ShadrixSilverquill extends CardImpl { + + private static final FilterPlayer filter0 = new FilterPlayer("a different player"); + private static final FilterPlayer filter1 = new FilterPlayer(); + private static final FilterPlayer filter2 = new FilterPlayer(); + private static final FilterPlayer filter3 = new FilterPlayer(); + + static { + filter1.add(new AnotherTargetPredicate(1, true)); + filter2.add(new AnotherTargetPredicate(2, true)); + filter3.add(new AnotherTargetPredicate(3, true)); + } + + public ShadrixSilverquill(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELDER); + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // At the beginning of combat on your turn, you may choose two. Each mode must target a different player. + Ability ability = new BeginningOfCombatTriggeredAbility(null, TargetController.YOU, false); + ability.getModes().setMinModes(2); + ability.getModes().setMaxModes(2); + ability.getModes().setMaxModesFilter(filter0); + ability.getModes().setMayChooseNone(true); + + // • Target player creates a 2/1 white and black Inkling creature token with flying. + ability.addEffect(new CreateTokenTargetEffect(new SilverquillToken())); + TargetPlayer target = new TargetPlayer(filter1); + target.setTargetTag(1); + ability.addTarget(target.withChooseHint("to create a token")); + + // • Target player draws a card and loses 1 life. + Mode mode = new Mode(new DrawCardTargetEffect(1)); + mode.addEffect(new LoseLifeTargetEffect(1).setText("and loses 1 life")); + target = new TargetPlayer(filter2); + target.setTargetTag(2); + mode.addTarget(target.withChooseHint("to draw a card and lose 1 life")); + ability.addMode(mode); + + // • Target player puts a +1/+1 counter on each creature they control. + mode = new Mode(new ShadrixSilverquillEffect()); + target = new TargetPlayer(filter3); + target.setTargetTag(3); + mode.addTarget(target.withChooseHint("to put a counter on each creature")); + ability.addMode(mode); + this.addAbility(ability); + } + + private ShadrixSilverquill(final ShadrixSilverquill card) { + super(card); + } + + @Override + public ShadrixSilverquill copy() { + return new ShadrixSilverquill(this); + } +} + +class ShadrixSilverquillEffect extends OneShotEffect { + + ShadrixSilverquillEffect() { + super(Outcome.Benefit); + staticText = "target player puts a +1/+1 counter on each creature they control"; + } + + private ShadrixSilverquillEffect(final ShadrixSilverquillEffect effect) { + super(effect); + } + + @Override + public ShadrixSilverquillEffect copy() { + return new ShadrixSilverquillEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (game.getPlayer(source.getFirstTarget()) == null) { + return false; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, + source.getFirstTarget(), source.getSourceId(), game + )) { + if (permanent == null) { + continue; + } + permanent.addCounters(CounterType.P1P1.createInstance(), source.getFirstTarget(), source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java b/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java index a7ce87199c..2c5b9578f9 100644 --- a/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java +++ b/Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java @@ -243,6 +243,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet { cards.add(new SetCardInfo("Semester's End", 27, Rarity.RARE, mage.cards.s.SemestersEnd.class)); cards.add(new SetCardInfo("Serpentine Curve", 52, Rarity.COMMON, mage.cards.s.SerpentineCurve.class)); cards.add(new SetCardInfo("Shadewing Laureate", 229, Rarity.UNCOMMON, mage.cards.s.ShadewingLaureate.class)); + cards.add(new SetCardInfo("Shadrix Silverquill", 230, Rarity.MYTHIC, mage.cards.s.ShadrixSilverquill.class)); cards.add(new SetCardInfo("Shaile, Dean of Radiance", 158, Rarity.RARE, mage.cards.s.ShaileDeanOfRadiance.class)); cards.add(new SetCardInfo("Shineshadow Snarl", 272, Rarity.RARE, mage.cards.s.ShineshadowSnarl.class)); cards.add(new SetCardInfo("Show of Confidence", 28, Rarity.UNCOMMON, mage.cards.s.ShowOfConfidence.class)); diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java index 464b26424d..4230bee2e9 100644 --- a/Mage/src/main/java/mage/abilities/Modes.java +++ b/Mage/src/main/java/mage/abilities/Modes.java @@ -10,6 +10,7 @@ import mage.filter.FilterPlayer; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.util.CardUtil; import mage.util.RandomUtil; import java.util.*; @@ -38,6 +39,7 @@ public class Modes extends LinkedHashMap<UUID, Mode> { private String chooseText = null; private boolean resetEachTurn = false; private Condition moreCondition; + private boolean mayChooseNone = false; public Modes() { this.currentMode = new Mode(); @@ -77,6 +79,7 @@ public class Modes extends LinkedHashMap<UUID, Mode> { this.currentMode = get(modes.getMode().getId()); // need fix? } this.moreCondition = modes.moreCondition; + this.mayChooseNone = modes.mayChooseNone; } public Modes copy() { @@ -326,7 +329,8 @@ public class Modes extends LinkedHashMap<UUID, Mode> { if (isEachModeOnlyOnce()) { setAlreadySelectedModes(source, game); } - return this.selectedModes.size() >= this.getMinModes(); + return this.selectedModes.size() >= this.getMinModes() + || (this.selectedModes.size() == 0 && mayChooseNone); } this.addSelectedMode(choice.getId()); if (currentMode == null) { @@ -460,26 +464,23 @@ public class Modes extends LinkedHashMap<UUID, Mode> { return this.getMode().getEffects().getText(this.getMode()); } StringBuilder sb = new StringBuilder(); + if (mayChooseNone) { + sb.append("you may "); + } if (this.chooseText != null) { sb.append(chooseText); - } else if (this.getMaxModesFilter() != null) { - sb.append("choose one or more. Each mode must target ").append(getMaxModesFilter().getMessage()); } else if (this.getMinModes() == 0 && this.getMaxModes(null, null) == 1) { sb.append("choose up to one"); - } else if (this.getMinModes() == 0 && this.getMaxModes(null, null) == 3) { + } else if (this.getMinModes() == 0 && this.getMaxModes(null, null) > 2) { sb.append("choose any number"); - } else if (this.getMinModes() == 1 && this.getMaxModes(null, null) > 2) { - sb.append("choose one or more"); } else if (this.getMinModes() == 1 && this.getMaxModes(null, null) == 2) { sb.append("choose one or both"); - } else if (this.getMinModes() == 2 && this.getMaxModes(null, null) == 2) { - sb.append("choose two"); - } else if (this.getMinModes() == 3 && this.getMaxModes(null, null) == 3) { - sb.append("choose three"); - } else if (this.getMinModes() == 4 && this.getMaxModes(null, null) == 4) { - sb.append("choose four"); + } else if (this.getMinModes() == 1 && this.getMaxModes(null, null) > 2) { + sb.append("choose one or more"); + } else if (this.getMinModes() == this.getMaxModes(null, null)) { + sb.append("choose " + CardUtil.numberToText(this.getMinModes())); } else { - sb.append("choose one"); + throw new UnsupportedOperationException("no text available for this selection of min and max modes"); } if (isEachModeOnlyOnce()) { @@ -489,7 +490,9 @@ public class Modes extends LinkedHashMap<UUID, Mode> { sb.append(" this turn"); } - if (isEachModeMoreThanOnce()) { + if (this.getMaxModesFilter() != null) { + sb.append(". Each mode must target ").append(getMaxModesFilter().getMessage()).append('.'); + } else if (isEachModeMoreThanOnce()) { sb.append(". You may choose the same mode more than once."); } else if (chooseText == null) { sb.append(" —"); @@ -540,4 +543,8 @@ public class Modes extends LinkedHashMap<UUID, Mode> { public void setChooseText(String chooseText) { this.chooseText = chooseText; } + + public void setMayChooseNone(boolean mayChooseNone) { + this.mayChooseNone = mayChooseNone; + } } diff --git a/Mage/src/main/java/mage/target/TargetPlayer.java b/Mage/src/main/java/mage/target/TargetPlayer.java index 2b7e126551..acd77cf0b5 100644 --- a/Mage/src/main/java/mage/target/TargetPlayer.java +++ b/Mage/src/main/java/mage/target/TargetPlayer.java @@ -21,6 +21,10 @@ public class TargetPlayer extends TargetImpl { this(1, 1, false); } + public TargetPlayer(FilterPlayer filter) { + this(1, 1, false, filter); + } + public TargetPlayer(int numTargets) { this(numTargets, numTargets, false); }